这篇文章主要介绍了如何使用C# Stopwatch 测量微秒精确度,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
跟同事讨论到- 用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数)。
第二版改用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
以上就是如何使用C# Stopwatch 测量微秒精确度的详细内容,更多关于C# Stopwatch 测量微秒精确度的资料请关注得得之家其它相关文章!
本文标题为:如何使用C# Stopwatch 测量微秒级精确度
基础教程推荐
- 覆盖 Json.Net 中的默认原始类型处理 2022-01-01
- Page.OnAppearing 中的 Xamarin.Forms Page.DisplayAlert 2022-01-01
- 创建属性设置器委托 2022-01-01
- 我什么时候应该使用 GC.SuppressFinalize()? 2022-01-01
- 从 VB6 迁移到 .NET/.NET Core 的最佳策略或工具 2022-01-01
- 当键值未知时反序列化 JSON 2022-01-01
- 如何使用OpenXML SDK将Excel转换为CSV? 2022-01-01
- C# - 将浮点数转换为整数...并根据余数更改整数 2022-01-01
- C# - 如何列出发布到 ASPX 页面的变量名称和值 2022-01-01
- 使用 SED 在 XML 标签之间提取值 2022-01-01