跟同事讨论到- 用C# Stopwatch 取得效能数值,Stopwatch.ElapsedMilliseconds 只到毫秒(ms),如果需要更高的时间精确度(微秒μs,甚至奈秒ns),该怎么做?

原以为要费番功夫,在Stackoverlow查到讨论,答案意外地简单。

准备测试程式如下,比较MD5 及SHA1 计算1MB byte[] 杂凑值所秏费时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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");
  }
}

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
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() 暖机。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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。

1
2
3
4
5
6
7
8
9
10
11
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。请看第三版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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");
  }
}

执行结果与第二版相同,但程式更简单一些。

1
2
3
4
5
6
7
8
9
10
11
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 测量微秒级精确度的更多相关文章

  1. Linux下的微秒级定时器: usleep, nanosleep, select, pselect

    Linux下的微秒级定时器: usleep, nanosleep, select, pselect 标签: linuxnulldelaystructdate 2012-02-07 23:29 4979 ...

  2. linux下C语言获取微秒级时间

    使用C语言在linux环境下获得微秒级时间 1.数据结构 int gettimeofday(struct timeval*tv, struct timezone *tz); 其参数tv是保存获取时间结 ...

  3. windows下实现微秒级的延时

    windowsintegeriostream汇编嵌入式任务 最近正在做一个嵌入式系统,是基于windows ce的,外接硬件的时序要微秒级的延时.1.微秒级的延时肯定不能基于消息(SetTimer函数 ...

  4. C++计时器:毫秒级和微秒级

    1.毫秒级 使用GetTickCount()获取系统启动所经过的毫秒数 #include<iostream> using namespace std; int main(){ DWORD ...

  5. shell脚本示例:计算毫秒级、微秒级时间差

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 有时候需要计算命令的执行时间长度,可以使用time命令,虽然t ...

  6. linux下获取微秒级精度的时间【转】

    转自:https://blog.csdn.net/u011857683/article/details/81320052 使用C语言在linux环境下获得微秒级时间 1. 数据结构 int getti ...

  7. 织女星开发板RISC-V内核实现微秒级精确延时

    前言 收到VEGA织女星开发板也有一段时间了,好久没玩了,想驱动个OLED屏,但是首先要实现IIC协议,而实现IIC协议,最基本的就是需要一个精确的延时函数,所以研究了一下如何来写一个精确的延时函数. ...

  8. windows下基于(QPC)实现的微秒级延时

    1.为什么会写windows下微秒级延时 在上一篇 实现memcpy()函数及过程总结 中测试memcpy的效率中,测试时间的拷贝效率在微秒级别,需要使用微秒级时间间隔计数. windows下提供Qu ...

  9. Golang在Linux系统中实现微秒级延迟

    在程序中延迟或者等待一段时间一般可以使用Sleep函数实现,但是因为操作系统线程调度的消耗,往往只能做到十几或者数十毫秒的精度,很难达到微秒级,Golang的time.Sleep也是如此. Sleep ...

  10. C++高精度计时器——微秒级时间统计

    在C++中,经常需要通过计时来统计性能信息,通过统计的耗时信息,来分析性能瓶颈,通常情况下,可能毫秒级别的时间统计就足够用了,但是在毫厘必争的性能热点的地方,毫秒级别的统计还是不够的,这种情况下,就需 ...

随机推荐

  1. ESP32-Arduino物联网工控(一)串口转TCP转发机项目简介

    Arduino 在物联网上配合ESP32简直就是神器! 然后现在大老板说新设备用ESP32来帮助原本没有联网功能的STM32单片机来进行调试...... 实现需求: 1.指定命令拍照,协议HTTP,并 ...

  2. 垃圾PTA:7-3 输出数组元素 (15分)

    本题要求编写程序,对顺序读入的n个整数,顺次计算后项减前项之差,并按每行三个元素的格式输出结果. 输入格式: 输入的第一行给出正整数n(1<n≤10).随后一行给出n个整数,其间以空格分隔. 输 ...

  3. Eplan是什么软件?学习Eplan软件的几个关键要点

    EPLAN是一款电气计算机辅助设计软件.我是一名Eplan软件的学习者,最近在学习这个专业的电气设计软件时,总结了一些关键要点,希望能与大家分享. 1. 熟悉软件界面和功能:首先,我们需要熟悉Epla ...

  4. 关于用PHP连接Mysql后添加数据,中文变成问号的解决方案

    这主要是编码问题,确认你在网页制作软件时所设定的编码,要与mysql的编码一致就可以解决 问题如下图: 打开这个表的操作页面,按下图设置: 排序规则里设置成你网页的编码方式,注意,要点选下面的Chan ...

  5. 7.Java SDK源码分析系列笔记-JDK1.8 HashMap

    目录 1. 是什么 2. 如何使用 3. 原理分析 3.1. uml 3.2. 构造方法 3.3. put方法 3.3.1. 计算key的hash值 3.3.2. 第一次进来table肯定为空,那么扩 ...

  6. vue入门(二)基于前面的基础的一个小Demo

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. com.alibaba的fastjson使用(持续添加)

    1.JSON换实体类T 1 //json是JSONObject类型,将json转成实体类T 2 T tt = JSONObject.parseObject(json.toJSONString(), T ...

  8. Codeforces Round #613 (Div. 2) ABC 题解

    A. Mezo Playing Zoma 题意:给你一个向右向左的指令,每个指令可以朝那个方向走一个单位,问你可以随意选出子序列来走,那可能到达的点有多少个. 思路:从范围上考虑就秒了.看最左和最右能 ...

  9. Linux 网络编程 简单 TCP连接sock连接的例子

    服务端 #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/t ...

  10. 关于人脸检测python库 dlib 初识 1

    简介 上了一门计算机视觉的课程,初步了解, dlib python库 参考链接 http://dlib.net/face_detector.py.html 人脸检测的链接 原理 This face d ...