我需要找到瓶颈,并尽可能准确地测量时间。
以下代码片段是否是衡量性能的最佳方式?
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
我需要找到瓶颈,并尽可能准确地测量时间。
以下代码片段是否是衡量性能的最佳方式?
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
微软的模式和实践小组在Visual Studio Team System Performance Testing Guidance中提供了一些指导。
Stopwatch sw = new Stopwatch();
sw.Start();
// Critical lines of code
long elapsedMs = sw.Elapsed.TotalMilliseconds;
这篇文章不够专业:
Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);
PerformWork();
int repeat = 1000;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
PerformWork();
}
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds / repeat);
在我的实际代码中,我将添加GC.Collect调用来改变托管堆的状态,然后添加Sleep调用,以便在ETW profile中轻松地分隔不同的代码间隔。
由于我并不太关注精度,因此最终将它们进行了比较。我正在捕获网络上的大量数据包,并希望在收到每个数据包时记录时间。这是测试 500 万次迭代的代码。
int iterations = 5000000;
// Test using datetime.now
{
var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (date == DateTime.Now)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using datetime.now. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
// Test using datetime.utcnow
{
var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (date == DateTime.UtcNow)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using datetime.utcnow. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
// Test using stopwatch
{
Stopwatch sw = new Stopwatch();
sw.Start();
var now = DateTime.UtcNow;
for (int i = 0; i < iterations; i++)
{
if (sw.ElapsedTicks == DateTime.Now.Ticks)
Console.WriteLine("it is!");
}
Console.WriteLine($"Done executing {iterations} iterations using stopwatch. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
}
输出结果为:
Done executing 5000000 iterations using datetime.now. It took 0.8685502 seconds
Done executing 5000000 iterations using datetime.utcnow. It took 0.1074324 seconds
Done executing 5000000 iterations using stopwatch. It took 0.9625021 seconds
因此总的来说,如果你不太关心精度,DateTime.UtcNow 是最快的。 这也支持这个问题的答案https://dev59.com/pnVD5IYBdhLWcg3wR5ko#6986472。
Stopwatch
执行所需的时间比实际上要多得多。在秒表测试中,您进行了额外的日期时间操作(sw.ElapsedTicks == DateTime.Now.Ticks
),这不仅需要从系统时钟获取当前时间,而且在此之前还需要将日期时间对象转换为当前时区,因为您使用的是DateTime.Now
而不是DateTime.UtcNow
。因此,您实际上是在测试DateTime.Now + Stopwatch
的执行时间,而不仅仅是Stopwatch
本身。 - undefinedDateTime.(Utc)Now.Ticks
的值,这样在我的机器上,以及在.NET 6和.NET Fiddle上运行时,Stopwatch
才是最快的。链接:https://dotnetfiddle.net/dSg3bN - undefined