内容简介:跟同事討論到 - 用 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协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ANTLR 4权威指南
Terence Parr / 张博 / 机械工业出版社 / 2017-5-1 / 69元
ANTLR是一款强大的语法分析器生成工具,可用于读取、处理、执行和翻译结构化的文本或二进制文件。它被广泛应用于学术领域和工业生产实践,是众多语言、工具和框架的基石。Twitter搜索使用ANTLR进行语法分析,每天处理超过20亿次查询;Hadoop生态系统中的Hive、Pig、数据仓库和分析系统所使用的语言都用到了ANTLR;Lex Machina将ANTLR用于分析法律文本;Oracle公司在S......一起来看看 《ANTLR 4权威指南》 这本书的介绍吧!