测量代码运行耗时的最佳方案:现有TimeWatch实现是否正确?
代码耗时计时方案评估与优化建议
现有代码的问题
你当前的实现逻辑核心通顺,但存在两个明显的可优化点:
- 冗余实例化:第一行
TimeWatch watch = new TimeWatch();属于无效代码,第二行你直接将TimeWatch.start()的返回值赋值给watch变量,前面new出来的对象会直接被GC回收,完全没有作用,直接合并成一行TimeWatch watch = TimeWatch.start();即可。 - 异常兼容缺失:如果目标代码段抛出异常,你最后一行的耗时统计逻辑会直接跳过,无法拿到执行耗时。
正确性判断
如果你的TimeWatch工具类的实现符合以下规范,那这段代码的统计逻辑是正确的:
start()方法内部调用的是System.nanoTime()而非System.currentTimeMillis():前者是JVM提供的单调递增时间,不受系统时间修改、网络时间同步的影响,专门用于时间间隔统计;后者是系统墙钟时间,用于计时会出现误差甚至负数的情况。time(TimeUnit.MILLISECONDS)方法返回的是从start()调用到当前方法调用的时间差,转换为指定单位返回。
注:如果你用的是Apache Commons Lang包的计时工具,类名实际为StopWatch,如果是自定义封装的TimeWatch请自行确认内部实现逻辑
最优方案建议
最优方案需要结合你的使用场景选择:
场景1:线上业务常规耗时统计
这是最常见的场景,只需要对异常兼容做优化即可,改进后的代码如下:
TimeWatch watch = TimeWatch.start(); double passedTimeInSeconds = 0d; try { // 待执行的目标代码段 } finally { passedTimeInSeconds = watch.time(TimeUnit.MILLISECONDS) / 1000.0; // 此处可添加耗时打印、上报等逻辑 }
如果需要更高的统计精度,也可以直接用纳秒单位统计再转换:
passedTimeInSeconds = watch.time(TimeUnit.NANOSECONDS) / 1e9;
场景2:性能基准测试
如果你是要做代码性能基准测试、对比不同实现的执行效率,那这个方案完全不适用。单次执行的耗时会受到JIT即时编译、垃圾回收、CPU调度等大量干扰因素的影响,统计结果误差极大。这种场景需要使用专门的基准测试框架JMH来完成,框架会自动处理预热、多轮迭代、干扰因素屏蔽等问题,统计结果更可信。
内容的提问来源于stack exchange,提问作者ness
相关产品推荐
相关产品推荐

