内容简介:跟同事討論到 - 用 C# Stopwatch 取得效能數值,Stopwatch.ElapsedMilliseconds 只到毫秒(ms),如果需要更高的時間精確度(微秒μs,甚至奈秒ns),該怎麼做?原以為要費番功夫,在 Stackoverlow 查到準備測試程式如下,比較 MD5 及 SHA1 計算 1MB byte[] 雜湊值所秏費時間:
跟同事討論到 - 用 C# Stopwatch 取得效能數值,Stopwatch.ElapsedMilliseconds 只到毫秒(ms),如果需要更高的時間精確度(微秒μs,甚至奈秒ns),該怎麼做?
原以為要費番功夫,在 Stackoverlow 查到 討論 ,答案意外地簡單。
準備測試程式如下,比較 MD5 及 SHA1 計算 1MB byte[] 雜湊值所秏費時間:
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");
}
}
執行結果如下:
Test 1 MD5 10ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms MD5 2ms SHA1 2ms
有兩個問題,第一是迴圈的第一次執行因涉及 .NET 初始化,耗時會異常偏高(先做 SHA1 再做 MD5,就變成第一筆 SHA1 超過 10ms),第二是 MD5 與 SHA1 執行時間相近,都是 2ms 多,用 ElapsedMilliseconds 看不出差異。
針對首次數值耗時偏差問題,除了略過第一次數據不計,我想到的另一個解法是在 Test1() 前先跑一次 MD5.Create() 完成相關初始化。至於 ElapsedMilliseconds 看不出差異問題,改用 ElapsedTicks 是種解法,但要注意,ElaspedTicks 換算成時間單位時,不是除以 TimeSpan.TicksPerMillisecond 而是依 CPU 頻率而定,需使用 Stopwatch.Frequency (每秒 Tick 數)。參考: Stopwatch.ElapsedTicks的祕密
第二版改用 ElapsedTicks * 1000000F / Stopwatch.Frequency 計算微秒(Microsecond, μs),執行前先 MD5.Create() 暖機。
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");
}
}
執行結果的第一次時間偏長問題消失,而也呈現出 SHA1 比 MD5 計算耗時的證據。而由數值來看,精確度可到 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
自己計算麻煩了點,Stopwatch 有個 Elapsed 屬性,型別為 TimeSpan,其中 TotalMilliseconds 屬性精確度即可達到 μs 及 100ns。請看第三版:
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");
}
}
執行結果與第二版相同,但程式更簡單一些。
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
Tips abougt how to get microsecond or nanosecond precision with C# Stopwatch.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- RecyclerView使用指南(一)—— 基本使用
- 如何使用Meteorjs使用URL参数
- 使用 defer 还是不使用 defer?
- 使用 Typescript 加强 Vuex 使用体验
- [译] 何时使用 Rust?何时使用 Go?
- UDP协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法设计与分析基础
Anany Levitin / 潘彦 / 清华大学出版社 / 2015-2-1 / 69.00元
作者基于丰富的教学经验,开发了一套全新的算法分类方法。该分类法站在通用问题求解策略的高度,对现有大多数算法准确分类,从而引领读者沿着一条清晰、一致、连贯的思路来探索算法设计与分析这一迷人领域。《算法设计与分析基础(第3版)》作为第3版,相对前版调整了多个章节的内容和顺序,同时增加了一些算法,并扩展了算法的应用,使得具体算法和通用算法设计技术的对应更加清晰有序;各章累计增加了70道习题,其中包括一些......一起来看看 《算法设计与分析基础》 这本书的介绍吧!