stopwatch 是生产环境唯一可靠的计时类,因其高精度、线程安全及易用性;应优先使用 startnew() 启动,复用时用 restart();区分 elapsedmilliseconds(截断整数)与 elapsed.totalmilliseconds(双精度小数);需检查 ishighresolution 并排除 jit 预热、gc 等干扰。

Stopwatch 是唯一值得在生产环境里用于测量代码耗时的类,DateTime.Now 和 Environment.TickCount 都不够准,尤其在短耗时场景下误差可能高达 15ms —— 这已经够执行好几次内存分配了。
Stopwatch.StartNew() 是最安全的启动方式
别用 new Stopwatch() + Start() 两步走,容易漏掉 Start() 导致 ElapsedMilliseconds 永远是 0。直接用静态方法一步到位:
-
Stopwatch sw = Stopwatch.StartNew();启动即计时,无需判空或状态检查 - 它内部会自动调用
Start(),且线程安全,适合在异步或并发上下文中使用 - 如果需要多次复用同一个实例(比如循环中测每次迭代),改用
Restart()更干净,它等价于Stop()+Reset()+Start()
ElapsedMilliseconds vs Elapsed.TotalMilliseconds 的区别必须清楚
这两个值看起来都返回毫秒,但底层行为完全不同:
-
ElapsedMilliseconds是long类型,只保留整数毫秒,小数部分直接截断(不是四舍五入) -
Elapsed.TotalMilliseconds是double类型,带完整小数精度,比如 1.003427ms,适合做除法求平均值 - 测单次短操作(如一次字典查找)时,
ElapsedMilliseconds很可能为 0;此时必须用Elapsed.TotalMilliseconds或ElapsedTicks配合Stopwatch.Frequency算纳秒
Stopwatch.IsHighResolution 决定了你能信多少数据
不是所有机器都支持高精度计时,得先确认硬件能力:
-
Stopwatch.IsHighResolution返回true表示正在用 CPU 周期级计数器(通常精度 ~100ns),这是理想状态 - 返回
false表示退化到系统时钟(Windows 上通常是 10–15ms 分辨率),这时候测任何低于 20ms 的操作都没意义 - 不要假设它一定高精度 —— 虚拟机、老旧 BIOS、某些省电策略都会禁用高精度计数器
真正影响结果的从来不是怎么写 StopWatch,而是你有没有关掉 JIT 预热干扰、有没有手动触发 GC、有没有在测量前跑一遍预热代码 —— 这些细节不处理,再准的计时器也只给你一个好看的假数字。











