如何使用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è)問題,第一是回圈的第一次執(zhí)行因涉及.NET 初始化,耗時(shí)會(huì)異常偏高(先做SHA1 再做MD5,就變成第一筆SHA1 超過10ms),第二是MD5 與SHA1 執(zhí)行時(shí)間相近,都是2ms 多,用ElapsedMilliseconds 看不出差異。
針對(duì)首次數(shù)值耗時(shí)偏差問題,除了略過第一次數(shù)據(jù)不計(jì),我想到的另一個(gè)解法是在Test1()前先跑一次MD5.Create()完成相關(guān)初始化。至于ElapsedMilliseconds看不出差異問題,改用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)問題消失,而也呈現(xiàn)出SHA1 比MD5 計(jì)算耗時(shí)的證據(jù)。而由數(shù)值來看,精確度可到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 屬性,型別為TimeSpan,其中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類相信大家都不陌生,這是一個(gè)Collection(集合)類型,可以通過Key/Value(鍵值對(duì)的形式來存放數(shù)據(jù);該類最大的優(yōu)點(diǎn)就是它查找元素的時(shí)間復(fù)雜度接近O(1)。那么什么樣的設(shè)計(jì)能使得Dictionary類實(shí)現(xiàn)O(1)的時(shí)間復(fù)雜度呢2021-06-06
C#連接Oracle數(shù)據(jù)庫的實(shí)例方法
C#連接Oracle數(shù)據(jù)庫的實(shí)例方法,需要的朋友可以參考一下2013-04-04
c#中利用委托反射將DataTable轉(zhuǎn)換為實(shí)體集的代碼
c#中利用委托反射將DataTable轉(zhuǎn)換為實(shí)體集的代碼,需要的朋友可以參考下2012-10-10
DevExpress實(shí)現(xiàn)GridControl列頭繪制Checkbox的方法
這篇文章主要介紹了DevExpress實(shí)現(xiàn)GridControl列頭繪制Checkbox的方法,需要的朋友可以參考下2014-08-08

