代码之家  ›  专栏  ›  技术社区  ›  Sergey Stadnik

正在优化日期时间的替代项。

  •  24
  • Sergey Stadnik  · 技术社区  · 5 年前

    我和一位同事在这个问题上来来回回,我希望就我提出的解决方案是否是一个好主意获得一些外部意见。

    首先,免责声明:我意识到“优化”的概念 DateTime.Now “你们中的一些人听起来很疯狂。我有一些先发制人的防御措施:

    1. 我有时怀疑那些总是说“计算机速度快,可读性好”的人 总是 “先于优化”通常指的是开发性能良好的应用程序的经验,尽管可能 重要的 ,不是 批评的 . 我说的是需要尽可能接近瞬间的事情发生——比如,在纳秒之内(在某些行业,这是 问题——例如,实时高频交易)。
    2. 即使考虑到这一点,我在下面描述的另一种方法实际上也是可读的。这不是一个奇怪的黑客,只是一个简单的方法,工作可靠和快速。
    3. 我们 运行测试。 日期时间 缓慢(相对而言)。下面的方法 更快。

    现在,讨论这个问题本身。

    基本上,从测试中,我们发现 日期时间。现在 运行大约需要25个滴答(大约2.5微秒)。当然,这是在数千到数百万次通话中平均得出的。似乎第一次调用实际上要花费大量时间,随后的调用要快得多。但是,平均有25个滴答。

    然而,我的同事和我注意到 DateTime.UtcNow 运行所需时间大大减少——平均仅为0.03微秒。

    如果夏令时发生变化,我们的应用程序将永远不会运行 ,我的建议是创建以下类:

    public static class FastDateTime {
        public static TimeSpan LocalUtcOffset { get; private set; }
    
        public static DateTime Now {
            get { return DateTime.UtcNow + LocalUtcOffset; }
        }
    
        static FastDateTime() {
            LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
        }
    }
    

    换句话说,确定本地时区的UTC偏移量 一旦 --在启动时——从那时起,利用 日期时间.utcnow 通过 FastDateTime.Now .

    如果在应用程序运行期间(例如,如果应用程序在夜间运行),UTC偏移量发生了变化,我可以看到这是一个问题;但是正如我已经说过的,在 我们的 这样的话,就不会发生了。

    我的同事对如何做这件事有不同的想法,这对我来说有点牵扯太多,无法在这里解释。最终, 据我所知 ,我们的两种方法都返回了一个准确的结果,我的速度稍快(约0.07微秒对约0.21微秒)。

    我想知道的是:

    1. 我是不是错过了什么?鉴于上述事实,应用程序只能在单个日期的时间范围内运行,是 快速日期时间。现在 安全吗?
    2. 其他人能想到一个偶数吗? 更快 获得当前时间的方法?
    4 回复  |  直到 8 年前
        1
  •  26
  •   Michael    15 年前

    您可以只使用datetime.utcnow,并且只在显示数据时转换为本地时间吗?您已经确定datetime.utcnow要快得多,它将消除DST周围的任何模糊性。

        2
  •  7
  •   Handcraftsman    14 年前

    结果之间的一个差异

    DateTime.Now
    

    DateTime.UtcNow + LocalUtcOffset 
    

    是kind属性的值-分别是local和utc。如果结果日期时间正在传递给第三方库,请考虑返回

    DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local)
    
        3
  •  5
  •   Jonathan Weinreb    8 年前

    我喜欢你的解决方案。 我做了一些测试,看它比普通的快多少 DateTime.Now

    DateTime.UtcNow 比…快117倍 日期时间

    使用 日期时间.utcnow 如果我们只对持续时间感兴趣,而不是对时间本身感兴趣,那就足够了。如果我们只需要计算特定代码段的持续时间(执行 duration= End_time - Start_time )那么时区就不重要了 数据处理程序 就足够了。

    但是如果我们需要时间本身,那么我们需要做 DateTime.UtcNow + LocalUtcOffset

    只是增加时间跨度会减慢一点 现在根据我的测试,我们的速度比一般的快49倍 日期时间

    如果我们按照建议将这个计算放在一个单独的函数/类中,那么调用这个方法会使我们的速度减慢得更慢。 我们的速度只有34倍。

    但即使是34倍的速度也很快!!!!

    简而言之, 使用 日期时间.utcnow 日期时间

    我发现提高建议课程的唯一方法是 内联代码: 日期时间.utcnow+localutcoffset 而不是调用类方法

    btw试图通过使用 [MethodImpl(MethodImplOptions.AggressiveInlining)] 似乎没有加快速度。

        4
  •  2
  •   dove    15 年前

    按相反顺序回答:

    2)我想不出更快的方法。

    1)值得检查的是,在管道中是否有类似的框架改进 just announced for System.IO

    很难确定安全性,但这正是很多单元测试所需要的东西。夏时制已经出现。系统一显然是非常坚固的战斗,而你的不是。