如何使用C# Stopwatch 測(cè)量微秒級(jí)精確度
跟同事討論到- 用C# Stopwatch 取得效能數(shù)值,Stopwatch.ElapsedMilliseconds 只到毫秒(ms),如果需要更高的時(shí)間精確度(微秒μs,甚至奈秒ns),該怎么做?
原以為要費(fèi)番功夫,在Stackoverlow查到討論,答案意外地簡(jiǎn)單。
準(zhǔn)備測(cè)試程式如下,比較MD5 及SHA1 計(jì)算1MB byte[] 雜湊值所秏費(fèi)時(shí)間:
static byte[] data = new byte[1024 * 1024]; static void Main(string[] args) { Test1(); Console.ReadLine(); } private static void Test1() { Console.WriteLine("Test 1"); for (var i = 0; i < 5; i++) { Stopwatch sw = new Stopwatch(); sw.Start(); var md5 = MD5.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"MD5 {sw.ElapsedMilliseconds}ms"); sw.Restart(); var sha1 = SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1 {sw.ElapsedMilliseconds}ms"); } }
執(zhí)行結(jié)果如下:
Test 1 MD5 10ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms
有兩個(gè)問(wèn)題,第一是回圈的第一次執(zhí)行因涉及.NET 初始化,耗時(shí)會(huì)異常偏高(先做SHA1 再做MD5,就變成第一筆SHA1 超過(guò)10ms),第二是MD5 與SHA1 執(zhí)行時(shí)間相近,都是2ms 多,用ElapsedMilliseconds 看不出差異。
針對(duì)首次數(shù)值耗時(shí)偏差問(wèn)題,除了略過(guò)第一次數(shù)據(jù)不計(jì),我想到的另一個(gè)解法是在Test1()前先跑一次MD5.Create()完成相關(guān)初始化。至于ElapsedMilliseconds看不出差異問(wèn)題,改用ElapsedTicks是種解法,但要注意,ElaspedTicks換算成時(shí)間單位時(shí),不是除以TimeSpan.TicksPerMillisecond而是依CPU頻率而定,需使用Stopwatch.Frequency (每秒Tick數(shù))。
第二版改用ElapsedTicks * 1000000F / Stopwatch.Frequency 計(jì)算微秒(Microsecond, μs),執(zhí)行前先MD5.Create() 暖機(jī)。
static byte[] data = new byte[1024 * 1024]; static void Main(string[] args) { MD5.Create(); Test2(); Console.ReadLine(); } private static void Test2() { Console.WriteLine("Test 2"); for (var i = 0; i < 5; i++) { Stopwatch sw = new Stopwatch(); sw.Start(); var md5 = MD5.Create().ComputeHash(data); sw.Stop(); // Console.WriteLine($"MD5 {sw.ElapsedTicks * 1000000F / Stopwatch.Frequency:n3}μs"); sw.Restart(); var sha1 = SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1 {sw.ElapsedTicks * 1000000F / Stopwatch.Frequency:n3}μs"); } }
執(zhí)行結(jié)果的第一次時(shí)間偏長(zhǎng)問(wèn)題消失,而也呈現(xiàn)出SHA1 比MD5 計(jì)算耗時(shí)的證據(jù)。而由數(shù)值來(lái)看,精確度可到0.1μs = 100ns。
Test 2 MD5 2,402.200μs SHA1 2,724.000μs MD5 2,017.300μs SHA1 2,576.900μs MD5 2,102.100μs SHA1 2,578.700μs MD5 2,024.100μs SHA1 2,600.300μs MD5 2,008.300μs SHA1 2,624.300μs
自己計(jì)算麻煩了點(diǎn),Stopwatch 有個(gè)Elapsed 屬性,型別為T(mén)imeSpan,其中TotalMilliseconds 屬性精確度即可達(dá)到μs 及100ns。請(qǐng)看第三版:
static byte[] data = new byte[1024 * 1024]; static void Main(string[] args) { MD5.Create(); Test3(); Console.ReadLine(); } private static void Test3() { Console.WriteLine("Test 3"); for (var i = 0; i < 5; i++) { Stopwatch sw = new Stopwatch(); sw.Start(); var md5 = MD5.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"MD5 {sw.Elapsed.TotalMilliseconds * 1000:n3}μs"); sw.Restart(); var sha1 = SHA1.Create().ComputeHash(data); sw.Stop(); Console.WriteLine($"SHA1 {sw.Elapsed.TotalMilliseconds * 1000:n3}μs"); } }
執(zhí)行結(jié)果與第二版相同,但程式更簡(jiǎn)單一些。
Test 3 MD5 2,423.400μs SHA1 2,692.400μs MD5 2,204.000μs SHA1 2,976.800μs MD5 2,094.500μs SHA1 2,588.600μs MD5 2,034.600μs SHA1 2,598.900μs MD5 2,029.900μs SHA1 2,887.000μs
以上就是如何使用C# Stopwatch 測(cè)量微秒精確度的詳細(xì)內(nèi)容,更多關(guān)于C# Stopwatch 測(cè)量微秒精確度的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
分析C# Dictionary的實(shí)現(xiàn)原理
對(duì)于C#中的Dictionary類(lèi)相信大家都不陌生,這是一個(gè)Collection(集合)類(lèi)型,可以通過(guò)Key/Value(鍵值對(duì)的形式來(lái)存放數(shù)據(jù);該類(lèi)最大的優(yōu)點(diǎn)就是它查找元素的時(shí)間復(fù)雜度接近O(1)。那么什么樣的設(shè)計(jì)能使得Dictionary類(lèi)實(shí)現(xiàn)O(1)的時(shí)間復(fù)雜度呢2021-06-06C#連接Oracle數(shù)據(jù)庫(kù)的實(shí)例方法
C#連接Oracle數(shù)據(jù)庫(kù)的實(shí)例方法,需要的朋友可以參考一下2013-04-04c#中利用委托反射將DataTable轉(zhuǎn)換為實(shí)體集的代碼
c#中利用委托反射將DataTable轉(zhuǎn)換為實(shí)體集的代碼,需要的朋友可以參考下2012-10-10C#自定義的字符串操作增強(qiáng)類(lèi)實(shí)例
這篇文章主要介紹了C#自定義的字符串操作增強(qiáng)類(lèi),涉及C#操作字符串實(shí)現(xiàn)分割、轉(zhuǎn)換、去重等常用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03DevExpress實(shí)現(xiàn)GridControl列頭繪制Checkbox的方法
這篇文章主要介紹了DevExpress實(shí)現(xiàn)GridControl列頭繪制Checkbox的方法,需要的朋友可以參考下2014-08-08