如何使用C# Stopwatch 测量微秒级精确度
跟同事讨论到-用C#Stopwatch取得效能数值,Stopwatch.ElapsedMilliseconds只到毫秒(ms),如果需要更高的时间精确度(微秒μs,甚至奈秒ns),该怎么做?
原以为要费番功夫,在Stackoverlow查到讨论,答案意外地简单。
准备测试程式如下,比较MD5及SHA1计算1MBbyte[]杂凑值所秏费时间:
staticbyte[]data=newbyte[1024*1024]; staticvoidMain(string[]args) { Test1(); Console.ReadLine(); } privatestaticvoidTest1() { Console.WriteLine("Test1"); for(vari=0;i<5;i++) { Stopwatchsw=newStopwatch(); sw.Start(); varmd5=MD5.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"MD5{sw.ElapsedMilliseconds}ms"); sw.Restart(); varsha1=SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1{sw.ElapsedMilliseconds}ms"); } }
执行结果如下:
Test1 MD510ms SHA12ms MD52ms SHA12ms MD52ms SHA12ms MD52ms SHA12ms MD52ms SHA12ms
有两个问题,第一是回圈的第一次执行因涉及.NET初始化,耗时会异常偏高(先做SHA1再做MD5,就变成第一笔SHA1超过10ms),第二是MD5与SHA1执行时间相近,都是2ms多,用ElapsedMilliseconds看不出差异。
针对首次数值耗时偏差问题,除了略过第一次数据不计,我想到的另一个解法是在Test1()前先跑一次MD5.Create()完成相关初始化。至于ElapsedMilliseconds看不出差异问题,改用ElapsedTicks是种解法,但要注意,ElaspedTicks换算成时间单位时,不是除以TimeSpan.TicksPerMillisecond而是依CPU频率而定,需使用Stopwatch.Frequency(每秒Tick数)。
第二版改用ElapsedTicks*1000000F/Stopwatch.Frequency计算微秒(Microsecond,μs),执行前先MD5.Create()暖机。
staticbyte[]data=newbyte[1024*1024]; staticvoidMain(string[]args) { MD5.Create(); Test2(); Console.ReadLine(); } privatestaticvoidTest2() { Console.WriteLine("Test2"); for(vari=0;i<5;i++) { Stopwatchsw=newStopwatch(); sw.Start(); varmd5=MD5.Create().ComputeHash(data); sw.Stop(); // Console.WriteLine($"MD5{sw.ElapsedTicks*1000000F/Stopwatch.Frequency:n3}μs"); sw.Restart(); varsha1=SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1{sw.ElapsedTicks*1000000F/Stopwatch.Frequency:n3}μs"); } }
执行结果的第一次时间偏长问题消失,而也呈现出SHA1比MD5计算耗时的证据。而由数值来看,精确度可到0.1μs=100ns。
Test2 MD52,402.200μs SHA12,724.000μs MD52,017.300μs SHA12,576.900μs MD52,102.100μs SHA12,578.700μs MD52,024.100μs SHA12,600.300μs MD52,008.300μs SHA12,624.300μs
自己计算麻烦了点,Stopwatch有个Elapsed属性,型别为TimeSpan,其中TotalMilliseconds属性精确度即可达到μs及100ns。请看第三版:
staticbyte[]data=newbyte[1024*1024]; staticvoidMain(string[]args) { MD5.Create(); Test3(); Console.ReadLine(); } privatestaticvoidTest3() { Console.WriteLine("Test3"); for(vari=0;i<5;i++) { Stopwatchsw=newStopwatch(); sw.Start(); varmd5=MD5.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"MD5{sw.Elapsed.TotalMilliseconds*1000:n3}μs"); sw.Restart(); varsha1=SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1{sw.Elapsed.TotalMilliseconds*1000:n3}μs"); } }
执行结果与第二版相同,但程式更简单一些。
Test3 MD52,423.400μs SHA12,692.400μs MD52,204.000μs SHA12,976.800μs MD52,094.500μs SHA12,588.600μs MD52,034.600μs SHA12,598.900μs MD52,029.900μs SHA12,887.000μs
以上就是如何使用C#Stopwatch测量微秒精确度的详细内容,更多关于C#Stopwatch测量微秒精确度的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。