C# 是DateTime。现在测量函数的最佳方法是';她的表现如何?
我需要找到一个瓶颈,需要尽可能准确地测量时间 下面的代码片段是度量性能的最佳方法吗C# 是DateTime。现在测量函数的最佳方法是';她的表现如何?,c#,.net,performance,datetime,timer,C#,.net,Performance,Datetime,Timer,我需要找到一个瓶颈,需要尽可能准确地测量时间 下面的代码片段是度量性能的最佳方法吗 DateTime startTime = DateTime.Now; // Some execution process DateTime endTime = DateTime.Now; TimeSpan totalTimeTaken = endTime.Subtract(startTime); 功能会更好(精度更高)。不过,我也建议只下载一个流行的评测器(也是我使用最多的评测器……DotTrace的免费试
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
功能会更好(精度更高)。不过,我也建议只下载一个流行的评测器(也是我使用最多的评测器……DotTrace的免费试用版功能齐全,不会像其他一些评测器那样唠叨)。不,不是。使用(在系统诊断中)
秒表自动检查是否存在高精度计时器
值得一提的是,DateTime.Now
通常比DateTime.UtcNow
慢一点,这是因为必须对时区等进行处理
DateTime.UtcNow的分辨率通常为15毫秒。请参阅关于DateTime.Now
precision以获得一个很好的摘要
有趣的琐事:如果您的硬件不支持高频计数器,秒表会回到DateTime.UtcNow
。通过查看静态字段,可以检查秒表是否使用硬件来实现高精度。使用System.Diagnostics.Stopwatch类
Stopwatch sw = new Stopwatch();
sw.Start();
// Do some code.
sw.Stop();
// sw.ElapsedMilliseconds = the time your "do some code" took.
我很少做这种性能检查(我倾向于认为“这很慢,让它更快”),所以我几乎总是这样做
谷歌确实透露了很多用于性能检查的资源/文章
许多人提到使用pinvoke获取性能信息。我研究的很多资料都只提到使用perfmon
编辑:
我看过秒表的谈话。。美好的我学到了一些东西:)
如果你想要快速而肮脏的东西,我建议你用秒表来代替,以获得更高的精确度
Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();
Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);
P>可选的,如果你需要更复杂的东西,你应该考虑使用第三方分析器,例如./P>@ /P>
仅供参考,.NET Timer类不用于诊断,它以预设间隔生成事件,如下所示(从):
所以,这并不能帮助你知道某件事花了多长时间,只是一段时间过去了
计时器也在System.Windows.Forms中作为控件公开。。。您可以在VS05/VS08中的designer工具箱中找到它,与秒表一样,它要好得多
关于绩效衡量,您还应该检查您的“//Some Execution Process”是否是一个非常短的过程
还要记住,第一次运行“//Some Execution Process”可能比后续运行慢得多
我通常通过在一个循环中运行1000次或1000000次来测试一个方法,我得到的数据比运行一次要准确得多。将基准测试代码推送到实用程序类/方法中非常有用。StopWatch
类不需要在出现错误时进行处理
或停止
。因此,对某些操作计时的最简单代码是
调用代码示例
public void Execute(Action action)
{
var time = With.Benchmark(action);
log.DebugFormat(“Did action in {0} ms.”, time);
}
public void Execute(Action action)
{
var time = action.Benchmark()
log.DebugFormat(“Did action in {0} ms.”, time);
}
这是扩展方法版本
public static class Extensions
{
public static long Benchmark(this Action action)
{
return With.Benchmark(action);
}
}
和示例调用代码
public void Execute(Action action)
{
var time = With.Benchmark(action);
log.DebugFormat(“Did action in {0} ms.”, time);
}
public void Execute(Action action)
{
var time = action.Benchmark()
log.DebugFormat(“Did action in {0} ms.”, time);
}
我刚在Vance Morrison的博客上找到一篇文章,内容是关于他写的,这篇文章使使用秒表变得更容易,并且做了一些简单的事情。Visual Studio Team System的一些功能可能有助于解决此问题。基本上,您可以编写单元测试,并将它们混合在不同的场景中,作为压力测试或负载测试的一部分针对您的软件运行。这可能有助于确定对应用程序性能影响最大的代码区域
微软的模式和实践小组提供了一些指导。这些都是测量时间的好方法,但这只是一种非常间接的方法来发现瓶颈
在线程中找到bottneck最直接的方法是让它运行,当它执行任何让您等待的操作时,使用暂停或断开键来停止它。这样做几次。如果瓶颈占用了X%的时间,则X%是您在每个快照的act中捕获瓶颈的概率
这是正确的方法:
using System;
using System.Diagnostics;
class Program
{
public static void Main()
{
Stopwatch stopWatch = Stopwatch.StartNew();
// some other code
stopWatch.Stop();
// this not correct to get full timer resolution
Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);
// Correct way to get accurate high precision timing
Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
}
}
有关更多信息,请浏览。表示,首先需要比较三种备选方案,秒表
,日期时间。现在
和日期时间.UtcNow
它还表明,在某些情况下(当性能计数器不存在时),秒表正在使用DateTime.UtcNow+一些额外的处理。因此,很明显,在这种情况下,DateTime.UtcNow是最好的选择(因为其他人使用它+一些处理)
然而,事实证明,计数器几乎总是存在的——请参阅
这是一个性能图。请注意UtcNow的性能成本与备选方案相比有多低:
X轴是样本数据大小,Y轴是示例的相对时间
秒表
更擅长的一点是它提供了更高分辨率的时间测量。另一个原因是它的OO特性。但是,围绕UtcNow
创建OO包装并不难。我在程序中使用的方法是使用StopWatch类,如图所示
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);
PerformWork();
int repeat=1000;
秒表sw=Stopwatch.StartNew();
for(int i=0;i
在我的实际代码中,我将添加GC.Collect调用以将托管堆更改为已知状态,并添加Sleep调用,以便在ETW配置文件中轻松分离不同的代码间隔。因为我不太关心精度,所以我最后比较了它们。我在网络上捕获了很多数据包,我想确定收到每个数据包的时间。下面是测试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");
}
总之,如果您不太在意精度,那么DateTime.UtcNow是最快的。这也支持答案f
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