C#中以毫秒为单位计算时间流逝

45

我需要计算一个用C#编写的代码序列的执行时间。使用DateTime.Now获取的毫秒值不正确。

 int start_time, elapsed_time;

 start_time = DateTime.Now.Millisecond;

 for(int i = 0; i < N_ITER; i++) {
       // cpu intensive sequence
 }

 elapsed_time = DateTime.Now.Millisecond - start_time;

elapsed_time 给出了负值。

如何替换 DateTime 以获取经过时间的实际值?


10
System.Diagnostics.Stopwatch 是一个用于测量时间间隔的类。 - L.B
5
当你不考虑时间戳的完整性时,有时会得到负值。例如,当时间在秒、分、时或毫秒发生变化时,只看时间戳的一部分可能会导致错误的结果,比如当前时间是50秒,15秒后它就会变成5秒,而不是65秒。因此,最好使用一个计时器或两个DateTime实例来记录开始和结束时间,并计算它们之间的时间差。例如:var st = DateTime.Now; Console.Write((DateTime.Now - st).ToString())。注意,这样可以避免出现负值。 - sameh.q
可能是测量代码执行时间的重复问题。 - Michael Freidgeim
7个回答

120
using System.Diagnostics;

//...

var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++) {
    // cpu intensive sequence
}
stopwatch.Stop();
elapsed_time = stopwatch.ElapsedMilliseconds;

16

根据评论修改的答案

本回答仅尝试计算两个时间点之间的总耗时毫秒数,其中这两个时间点直接来自于DateTime.Now。根据讨论,了解到DateTime.Now容易受到外部影响,因此最好的解决方案是使用Stopwatch类。以下链接较好地解释和讨论了DateTimeNowDateTime.TicksStopWatch的性能区别(个人认为):performance between DateTimeNow, DateTime.Ticks, StopWatch

原始回答:

你将它转换为int的方式有问题。你需要更好的类型转换和额外的元素 :) 与一个高效的计时器相比,这可能看起来很简单。但它有效:

DateTime startTime, endTime;
startTime = DateTime.Now;

//do your work

endTime = DateTime.Now;
Double elapsedMillisecs = ((TimeSpan)(endTime - startTime)).TotalMilliseconds;

在网络上有一个参考资料,你可能也想查看一下。


1
那与问题无关。 DateTime.Now 以文件时间的形式返回系统时间,这可以因为十几个原因而有所不同。 Stopwatch 费力地设置了每秒 / 毫秒等经过的系统滴答数,并基本上设置了自己的环境来进行测量。 当像这样对事物进行基准测试时,这正是您需要做的,因此它是可重复的。 - tmesser
我正准备询问它们之间的区别,所以谢谢。 - Sebi
你们评论得太快了,而我还在写我的答案。请看完整的答案。 - bonCodigo
@bonCodigo,您提供的链接是完全不同的应用程序,原因之一是它是一个Web /表单应用程序,而不是基准测试应用程序。我没有给您投反对票,但是谁投了反对票都是有充分理由的,因为您使用了错误的工具来完成手头的工作。如果您想争辩这一点,您应该首先展示DateTime.Now不能受外部因素的影响。考虑到它从外部资源中特别提取其值,我认为您会发现这很困难。 - tmesser
如果我们分解OP的主要意图,他想找出在开始时间和结束时间之间以毫秒为单位的总经过时间。所以我根据这个提供了答案,并且它有效。然而,当我理解到“解决方案应该独立于DATETIME.NOW上的任何影响”--->那显然意味着我的答案不能使用。因此,在这种情况下,我会在答案上加注释。但是就逻辑而言,这可以找到两个时间之间以毫秒为单位的经过时间,忽略对DateTime.Now的任何影响。 - bonCodigo
显示剩余3条评论

6
你需要使用Stopwatch类来实现高精度时间测量。
var stopwatch = new Stopwatch();

stopwatch.Start();
for (int i = 0; i < N_ITER; i++)
{
     // cpu intensive sequence
}
stopwatch.Stop();

var elapsed = stopwatch.ElapsedMilliseconds;

3

2
DateTime.Millisecond”仅返回秒的毫秒部分,范围为0-999。在进行计时时,您需要考虑日期时间的其余部分。
但是,您应该考虑使用StopWatch类来进行这些类型的性能计时。

1
这对我有用:

这适用于我:

var lapsedTime = DateTime.Now.Subtract(beginTime).TotalMilliseconds;

0

这是我用来获取简单计算时间的方法:

class Program
{
    static void Main(string[] args)
    {
        Decimal p = 0.00001m;
        Decimal i = 0m;
        DateTime start = new DateTime();
        DateTime stop = new DateTime();

        for (i = p; i <= 5; i = i + p)
        {
            Console.WriteLine("result is: " + i);
            if (i==p) start = DateTime.Now;
            if (i==5) stop = DateTime.Now;
        }

        Console.WriteLine("Time to compute: " + (stop-start));

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接