【问题标题】:efficient way to get current time获取当前时间的有效方法
【发布时间】:2013-10-15 21:41:53
【问题描述】:

我正在使用 c#,据我了解(主要来自使用 c++),获取系统时间 DateTime.Now 可能会很慢。我正在尝试通过使用计时器来改进这一点/Stopwatch

class Time {
    private DateTime _starttime;
    private Stopwatch _timer;

    public Time() {
        _timer = new Stopwatch();
        _starttime = DateTime.Now; //trying to improve on multiple calls to `DateTime.Now` by only calling it once
        _timer.start;
    }

    public DateTime Now {
        get { return _starttime + _timer.Elapsed; }
    }

}

现在我的班级可以有一个成员private Time _time; 并在想知道当前时间的任何时候拨打_time.Now;

我当前的时间可能会有一点偏差(我正在尝试测量延迟并想知道我是否慢了几秒钟或更长时间),但我确实希望能够查看当前时间很多系统调用不会对性能造成影响。

当我开始创建一些性能测试时,我想知道是否有人知道更好/不同的方法(或者也许有人知道我是否完全不在此列)。

【问题讨论】:

  • 你从哪里听说DateTime.Now 很慢?不是。
  • 听说过Premature Optimization吗?
  • @MarkB42:“每分钟 100 多条消息”是一个 很小 的数字,除非“+”真的意味着“减少了几个数量级”。你真的担心这个吗?在我的笔记本电脑上,调用DateTime.Now 1000 万 次大约需要 4 秒。调用DateTime.UtcNow 1000 万次(无论如何这可能是一个更好的主意——如果可以的话,在任何地方都使用 UTC)需要 82 毫秒。仍然认为您需要优化?
  • @JonSkeet 我认为 MarkB42 不需要优化。我认为他需要你的笔记本电脑。 :)
  • @MarkB42:现在是停止猜测并使用分析器的好时机。性能问题通常非常令人惊讶 - 通过测量和测试,您会比通过猜测更快地找到问题的根源,IMO。我仍然建议使用UtcNow 而不是Now,请注意...

标签: c# datetime


【解决方案1】:

在 SO 上查看这个问题,讨论为什么 DateTime.Now 和 DateTime.UtcNow 如此缓慢/昂贵...

Why are DateTime.Now DateTime.UtcNow so slow/expensive

如果您在该线程中查看我的答案(我没有任何信息说明为什么这些操作“如此缓慢”(如果确实如此的话)),但我确实分享了一些来自 NLog 的代码,这显然是尝试在当前时间可能有很多请求的情况下优化当前时间的检索。

本质上,NLog 在判断当前时间的时候,缓存的是 DateTime.UtcNow 的结果。对于未来的请求,如果当前滴答计数(Environment.TickCount)与上次相同,则返回缓存的 DateTime.UtcNow 值。否则,获取当前的 DateTime.UtcNow 值并保存 Environment.TickCount。

无论 DateTime.Now 和 DateTime.UtcNow 是否“慢”,NLog 代码确实提供了一种有趣的方式来避免获取当前时间的“慢”部分,如果 DateTime.Now (或 DateTime.UtcNow) 将与上次调用它的时间相同。我没有对它进行基准测试,所以我不能告诉你这是否真的更快。或者,如果是,您将执行多少当前时间操作才能看到收益。

祝你好运!

【讨论】:

    【解决方案2】:

    我很好奇,所以我检查了一下。 DateTime.Now 内部调用DateTime.UtcNow,后者又调用内部 CLR 方法:

    DateTime.GetSystemTimeAsFileTime()
    

    这里是 MSDN documentation 的方法,这里是 stackoverflow post 的详细信息。

    【讨论】:

    • 重要的是,它会调用UtcNow 然后进行时区计算(这可能没有那么快)。
    • 在测试我们的应用程序时,我们发现 DateTime.Now 实际上是“最糟糕的”内存分配违规者之一,因为它每次访问时都会执行大量的 TZ/文化工作.. DateTime.UtcNow 避免了尽管在大多数情况下两者都“足够快”。 DateTime.UtcNow 只调用 GetSystemTimeAsFileTime 并进行一些数学运算,因此它具有与直接内部调用大致相同的“性能”,但可访问并产生更友好的 DateTime 对象..
    猜你喜欢
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多