Beware of the stopwatch
来源:互联网 发布:linux mv到当前目录 编辑:程序博客网 时间:2024/05/16 05:50
In a comment on my last post, craniac argued that the StopWatch-class should be used for measuring time intervals.
Sadly, measuring a time interval is not as easy as it sounds. There are several mechanisms, I will explain 3 of them and point out their strengths and weaknesses.
1. DateTime.UtcNow
1: DateTime begin = DateTime.UtcNow;
2:
3: ...
4:
5: DateTime end = DateTime.UtcNow;
6: Console.WriteLine("Measured time: " + (end-begin).TotalMilliseconds + " ms.");
This is the fastest mechanism because under the hood it only reads a counter from memory (the code above takes only 76 nanoseconds to execute on my machine). However the resolution is not so great: only 10 milliseconds on recent version of Windows. If you want to measure a piece of code that takes shorter to execute, you will have to execute it e.g. 1000 times and measure how long this takes, then divide the result by 1000.
Another disadvantage is that this is not reliable if the system-time changes. This should be a very rare situation, but could for instance happen through synchronization with a time server.
2. Stopwatch
1: Stopwatch watch = new Stopwatch();
2: watch.Start();
3:
4: ...
5:
6: watch.Stop();
7: Console.WriteLine("Measured time: " + watch.Elapsed.TotalMilliseconds + " ms.");
This mechanism is a bit slower than the previous one (10 times slower on my machine) so for short intervals this may have an impact on the result. However there are some serious issues:
- This can be unreliable on a PC with multiple processors. Due to a bug in the BIOS, Start() and Stop() must be executed on the same processor to get a correct result.
- This is unreliable on processors that do not have a constant clock speed (most processors can reduce the clock speed to conserve energy). This is explained in detail here.
I suspect that you can get a reliable result if you run it on a single-processor machine and disable any power-saving options in the BIOS. I haven’t tested this though.
On the upside, it has the hightest possible resolution (which depends on the hardware it runs on).
3. Process.TotalProcessorTime
1: TimeSpan begin = Process.GetCurrentProcess().TotalProcessorTime;
2:
3: ...
4:
5: TimeSpan end = Process.GetCurrentProcess().TotalProcessorTime;
6: Console.WriteLine("Measured time: " + (end - begin).TotalMilliseconds + " ms.");
This mechanism is different from the previous ones because it does not measure how much time has passed, but it measures how long your process has kept the CPU busy. This is great for performance measurements:
- The timings are not distorted by other processes that consume a lot of CPU.
- You can measure the impact that your code has on the overall performance of the system. On laptops, this also gives an indication towards the battery-power that is consumed by your process. This can be important for applications that run for a long time (such as services and other background tasks).
To interpret the measured time correctly, you should realize that time that is spent while your code is waiting (e.g. in a Sleep) will not be counted. On the other hand, if your process is keeping multiple processors busy, the time of each processor will be added (if a dual-core processor is kept 100% busy, the ‘TotalProcessorTime’ will increment with 2 each second!).
Note that this mechanism has the worst performance: the code above takes 19264 nanoseconds on my PC. This is 250 times slower than using DateTime.UtcNow!
So there is not one-size-fits-all solution to measure a time interval. Personally, if I want to measure how long a piece of code takes to execute, I run it in a loop (e.g. one million times) and measure it using DateTime.UtcNow.
- Beware of the stopwatch
- Beware the Share
- Beware the Share
- Beware the Share
- Beware of GPU memory bandwidth!!
- Beware of unknown root causes
- Beware the C++ implicit conversion
- 作业Week3 "Stopwatch: The Game"
- 2.3谨慎活跃问题(Beware of Liveness Problems)
- Hackers Beware: The Ultimate Guide to Network Security
- Stopwatch
- Stopwatch
- Stopwatch
- StopWatch
- Stopwatch
- Mini-project # 3 - "Stopwatch: The Game"
- [转]Beware of Hot Skills Lists: a JonERP.com Disclaimer and Tips List
- Effective Objective-C 2.0: Item 32: Beware of Memory Management with Exception-Safe Code
- Arduino入门函数笔记
- Unity UGUI优化
- 关于 验证码 Ajax,jQuery,Cookie与Session 总结
- mavn的安装与本地仓库的搭建
- 解决:angular js模板中无法使用ueditor的问题
- Beware of the stopwatch
- 10:数字组合
- 4.Django入门:教程-管理站点
- sonar常见错误以及处理方案
- C#委托的测试
- Struts2学习(1):Struts2框架结构详解
- Tomcat7.0安装配置详细(图文)
- #18.2#3D数学-向量(Vector)
- mybatis的设置