可能是重复问题:
我如何测量一个函数的运行时间?
我有一个需要花费I/O时间的方法,它会将数据从一个位置复制到另一个位置。计算执行时间的最佳和最真实的方法是什么? Thread
? Timer
? Stopwatch
? 还有其他解决方案吗?我想要最精确的方法,并且尽可能简洁。
从个人经验来看,System.Diagnostics.Stopwatch
类可用于测量方法的执行时间,但是请注意:它并不完全准确!
考虑以下示例:
Stopwatch sw;
for(int index = 0; index < 10; index++)
{
sw = Stopwatch.StartNew();
DoSomething();
Console.WriteLine(sw.ElapsedMilliseconds);
}
sw.Stop();
示例结果
132ms
4ms
3ms
3ms
2ms
3ms
34ms
2ms
1ms
1ms
现在你可能会想:"为什么第一次需要132ms,而之后的时间明显更短?"
答案是, Stopwatch
在 .NET 中并不会对 "背景噪声" 活动进行补偿,例如 JITing。因此,在第一次运行方法时,.NET 首先要进行 JITing。执行此操作所需的时间将添加到执行时间中。同样,其他因素也会导致执行时间变化。
如果您真正想要绝对准确性,应该寻找 性能分析!
看看下面的内容:
RedGate ANTS 性能分析器是一款商业产品,但可以产生非常精确的结果。 - 使用.NET分析性能来提升应用性能
这里有一个关于分析性能的 StackOverflow 文章:- 有哪些好的.NET分析器?
我还写了一篇关于使用 Stopwatch 进行性能分析的文章,您可能会感兴趣 - .NET 的性能分析
StopWatch
类帮助你找到最佳解决方案。
Stopwatch sw = Stopwatch.StartNew();
DoSomeWork();
sw.Stop();
Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);
此外,它还有一个名为Stopwatch.IsHighResolution
的静态字段。当然,这是硬件和操作系统问题。
指示计时器是否基于高分辨率性能计数器。
如果您对性能感兴趣,最好的答案是使用分析器。
否则,System.Diagnostics.StopWatch 提供高分辨率计时器。
根据这个微软文档:
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
}
输出:
运行时间 00:00:09.94
System.Environment.TickCount
举个例子
static void method1()
{
for (int i = 1; i <= 100; i++)
{
Console.WriteLine("Test1 " + i);
}
}
static void Main(string[] args)
{
var startTime = Environment.TickCount;
method1();
var endTime = Environment.TickCount;
Console.WriteLine("RunTime " + (endTime - startTime));
}
StopWatch将使用高分辨率计数器
秒表通过计算底层计时器机制中的计时器滴答声来测量经过的时间。如果安装的硬件和操作系统支持高分辨率性能计数器,则Stopwatch类使用该计数器来测量经过的时间。否则,Stopwatch类使用系统计时器来测量经过的时间。使用Frequency和IsHighResolution字段来确定Stopwatch计时实现的精度和分辨率。
如果您正在测量IO,则您的数字可能会受到外部事件的影响,我不会太担心准确性(如上所述)。相反,我会进行一系列测量,并考虑这些数字的平均值和分布。
using System.Diagnostics;
class Program
{
static void Test1()
{
for (int i = 1; i <= 100; i++)
{
Console.WriteLine("Test1 " + i);
}
}
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Test1();
sw.Stop();
Console.WriteLine("Time Taken-->{0}",sw.ElapsedMilliseconds);
}
}
ThreadPool.QueueUserWorkItem(delegate { CopyFiles(folder, dest); });
,但是秒表在所有操作完成之前就停止了。 - Mahdi Tahsildari