【问题标题】:Fastest way to calculate time differences in C#?在 C# 中计算时差的最快方法是什么?
【发布时间】:2011-11-15 08:49:21
【问题描述】:

在 C# 中似乎有很多方法可以计算时间跨度。我想知道哪个是最快的,我只是说需要最少的处理量。让我举一个例子来说明我想要做什么。

private const int timeBetweenEvents = 250;    //delay ms
DateTime nextUpdate = DateTime.Now.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
...
while(true)
{
   if (DateTime.Now > nextUpdate)
   {
       // do something
       nextUpdate = DateTime.Now.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
   }
   // ...
   // do some other stuff
   // ...
}

另一种选择...

private const int timeBetweenEvents = 250;    //delay ms
TimeSpan nextUpdate = DateTime.Now.TimeOfDay.Add(new TimeSpan(0,0,0,timeBetweenEvents));
...
while(true)
{
   if (DateTime.Now.TimeOfDay > nextUpdate)
   {
       // do something
       nextUpdate = DateTime.Now.TimeOfDay.Add(new TimeSpan(0, 0, 0, timeBetweenEvents));
   }
   // ...
   // do some other stuff
   // ...
}

通过使用 System.Environment.TickCount 进行减法,我也看到了类似的情况。那么最好的方法是什么?

【问题讨论】:

  • 你想用这个时间戳做什么?看起来你只需要 Timer
  • 最适合什么?可读性?准确性?表现?还有什么?
  • @Oded,既然标题是最快的,我会假设性能。
  • 您的第二个代码 sn-p 甚至无法编译...您应该在性能之前专注于正确性。你有多确定最简单的代码对你来说性能不够好? (为了清楚起见,我还鼓励您使用 TimeSpan.FromMilliseconds 等。)
  • 如果您进行少量计算,我认为您选择哪种方法是任意的。如果你做了大量的工作,那么它只会受到你选择的方法的影响。

标签: c# performance time timespan


【解决方案1】:

我会使用Timer

【讨论】:

  • 绝对正确的答案。 OP 似乎正在形成一个紧密循环,检查时间,然后在需要时触发事件。计时器会更有效地执行此操作。我更喜欢System.Threading.Timer,但每个人都有自己的。
  • Timer 比 DateTime 或 StopWatch 有一个优势:您可以摆脱 while(true) 循环并改用异步事件 (Timer.Elapsed)。您的链接有一个简单的示例。
  • @spender 我认为 Jordan S 可以同时尝试 System.Threading.Timer 和 System.Timers.Timer 看看哪个最适合她的需求
  • @ThiagoAlves:除非你有支持性证据,否则我认为假设 Jordan 是一个女孩的名字是很危险的;)
  • @ThiagoAlves:spender 是正确的。我绝对是男的!说真的,SO上有多少女孩?
【解决方案2】:

如果您正在寻找性能,至少在循环之外缓存DateTime.Now 的值。我记得阅读它可能是一个相对昂贵的调用函数。

【讨论】:

  • 这个问题被否决的原因是什么?作者对性能很感兴趣,Kurru 提出了一个非常好的观点,DateTime.Now 是一个昂贵的函数。
  • 语句new TimeSpan(0, 0, 0, timeBetweenEvents) 也应该在循环之外。
  • 因为 DateTime.Now 变量将保持不变并且 if 条件永远不会评估为 true ?
  • 我的意思更多是作为一般建议,但是,它仍然可以部分缓存以将调用次数减少一半。显然,您还需要一些 Sleeps 以将 CPU 使用率从 100% 降低...
  • 是的,所以睡眠间隔减去执行 Do Something 代码的时间,任意间隔睡眠没有意义。
【解决方案3】:

StopWatch 的精度会更高。

【讨论】:

    【解决方案4】:

    DateTimeEnvironment.TickCountThread.Sleep 的分辨率为 30 毫秒 - 这可能会导致问题。 Stopwatch 没有这个问题(在支持它的平台上,即今天几乎所有的机器上)——而且代码也更短一些(最快的代码是永远不会执行的代码)并且更清晰。

    const long millisecondsBetweenEvents = 250;
    var sw = new Stopwatch();
    
    sw.Start();
    while(true)
    {
       if (sw.ElapsedMilliseconds > millisecondsBetweenEvents)
       {
          // do something
          sw.Restart();
       }
    }
    

    【讨论】:

    • 哎哟。虽然回答了 OP 提出的问题,但请退后一步,看看这段代码是如何实际运行的。这是邪恶的。正确的答案是推荐使用定时器。
    • @spender 如果你想要 >30ms 的间隔。如果指定了
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 2017-06-27
    • 2011-02-25
    • 1970-01-01
    • 2020-09-26
    • 2020-11-13
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多