C# 优化DateTime的替代方案。现在

C# 优化DateTime的替代方案。现在,c#,.net,performance,datetime,optimization,C#,.net,Performance,Datetime,Optimization,我和一位同事在这个问题上反复讨论,我希望能得到一些外界的意见,看看我提出的解决方案是否是个好主意 首先,免责声明:我意识到“优化DateTime.Now”的概念对你们中的一些人来说听起来很疯狂。我有几个先发制人的防御措施: 我有时怀疑,那些总是说“计算机速度快;可读性总是先于优化”的人,常常是从开发性能(尽管可能很重要)并不重要的应用程序的经验中说起的。我说的是需要事情尽可能地在瞬间发生——比如,在纳秒之内(在某些行业,这确实很重要——例如,实时高频交易) 即使考虑到这一点,我在下面描述的另一种

我和一位同事在这个问题上反复讨论,我希望能得到一些外界的意见,看看我提出的解决方案是否是个好主意

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

  • 我有时怀疑,那些总是说“计算机速度快;可读性总是先于优化”的人,常常是从开发性能(尽管可能很重要)并不重要的应用程序的经验中说起的。我说的是需要事情尽可能地在瞬间发生——比如,在纳秒之内(在某些行业,这确实很重要——例如,实时高频交易)
  • 即使考虑到这一点,我在下面描述的另一种方法实际上也是可读的。这不是一个奇怪的黑客,只是一个简单的方法,工作可靠,速度快
  • 我们有运行测试<代码>日期时间。现在比较慢(相对而言)。下面的方法速度更快
  • 现在,谈谈问题本身

    基本上,通过测试,我们发现
    DateTime.Now
    运行大约需要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偏移量一次,然后从那时起利用
    DateTime.UtcNow
    的速度,通过
    FastDateTime.Now
    更快地获取当前时间

    如果UTC偏移量在应用程序运行期间发生变化(例如,如果应用程序在夜间运行),我会认为这是一个问题;但正如我已经说过的,在我们的情况下,这不会发生

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

    我想知道的是:

  • 我是不是遗漏了什么?鉴于上述事实,应用程序将仅在单个日期的时间范围内运行,
    FastDateTime.Now
    safe
  • 其他人能想出一种更快的方法来获取当前时间吗

  • 按相反顺序回答:

    2) 我想不出更快的办法

    1) 值得检查的是,管道中是否有任何框架改进


    很难确定安全性,但这是需要大量单元测试的。我想到了夏令时。System one显然是非常久经考验的,而您的System one则不是。

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

    结果之间的一个差异

    DateTime.Now
    

    是种类属性的值-分别为Local和Utc。如果生成的DATE时间传递给第三方库,则考虑返回

    DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local)
    
    我喜欢你的解决方案。 我做了一些测试,看看它比常规的
    DateTime快多少

    DateTime.UtcNow
    DateTime.Now快117倍

    如果我们只关心持续时间而不是时间本身,那么使用
    DateTime.UtcNow
    就足够了。如果我们只需要计算特定代码段的持续时间(doing
    duration=End\u time-Start\u time
    ),那么时区并不重要,而
    DateTime.UtcNow
    就足够了

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

    只需增加时间跨度,速度就会慢一点 现在根据我的测试,我们只比常规的
    DateTime快49倍

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

    但即使是34倍的速度也太快了

    总之,, 使用
    DateTime.UtcNow
    DateTime.Now要快得多

    我发现改进建议类的唯一方法是使用 内联代码:
    DateTime.UtcNow+LocalUtcOffset
    而不是调用类方法

    顺便说一句,试图通过使用
    [MethodImpl(methodimpoptions.aggressiveinline)]

    似乎没有加快速度。

    在进行此类简化时,DST转换通常是疏忽,您已经规定这不会成为问题。当人们发现他们(及其应用软件)生活在两个时区时,他们会措手不及,一动不动。更棘手的是,您的测试套件捕捉到这一点的唯一时间是它在DST转换期间运行,这最多是一种罕见的情况(或者被模拟为测试套件的一部分,我断言这是一种更罕见的情况)。+1我读到UtcNow的速度要快得多,这让我感到惊讶。我将继续接受这个答案,因为它非常有意义。不幸的是,我不认为我们会这样做(至少还没有),因为我们需要修改大量的代码。但这是一个错误
    DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local)