返回

花样验证代码运行时间,技术实力瞬间提升

后端

代码运行时间测量:告别 System.currentTimeMillis

System.currentTimeMillis() 的陷阱

当提到代码运行时间的测量,大多数程序员的首选工具都是 System.currentTimeMillis()。它简单易用,只需调用就能获得当前时间戳,通过减去先前调用值便可计算运行时间。然而,System.currentTimeMillis() 暗藏了一个致命缺陷:它更适合用于计算时间点,而非时间间隔。

原因在于,System.currentTimeMillis() 返回一个表示从 1970 年 1 月 1 日 0 时 0 分 0 秒到当前时间的毫秒数。这是一个单调递增的值,不会跳跃或回退。

但在测量代码运行时间时,System.currentTimeMillis() 会遇到问题。在某些情况下,它的值可能在极短的时间内多次改变。例如,系统时间调整或计算机进入休眠状态时,System.currentTimeMillis() 的值可能突然变化。

这会导致使用 System.currentTimeMillis() 计算的代码运行时间出现误差。因此,为了更精确地测量代码运行时间,最好另觅良方。

代码运行时间测量的进阶技巧

除 System.currentTimeMillis() 外,还有多种测量代码运行时间的方法,各有优缺点,适用场景不一。

  • System.nanoTime() :返回从特定固定时间点到当前时间的纳秒数,精度更高,可达纳秒级。不过,它的返回值是一个难以理解和处理的 long 型数字。
long startTime = System.nanoTime();
// 运行代码
long endTime = System.nanoTime();
long duration = endTime - startTime; // 运行时间(纳秒)
  • Stopwatch :一个用于测量代码运行时间的类,提供了 start()、stop() 和 getElapsedTime() 等方法。精度高,可达纳秒级。但需要手动启动和停止,比较麻烦。
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
// 运行代码
stopwatch.stop();
long duration = stopwatch.getElapsedTime(); // 运行时间(纳秒)
  • JMH :一个 Java 微基准测试框架,功能强大,可帮助更精确地测量代码运行时间。但复杂度较高,需要一定的学习成本。

选择适合你的方法

选择代码运行时间测量方法时,需要考虑以下因素:

  • 精度 :所需精度有多高?
  • 易用性 :是否希望使用简单易用的方法?
  • 性能 :是否需要高性能的方法?

根据这些因素,即可选择最适合的代码运行时间测量方法。

代码运行时间优化技巧

除了选择合适的测量方法,还可以通过一些技巧来优化代码运行时间:

  • 减少不必要的循环 :循环会消耗大量性能,应尽可能减少不必要的循环。
  • 使用高效的数据结构 :选择适合代码需求的高效数据结构。
  • 避免阻塞操作 :阻塞操作会使线程挂起,导致代码运行速度变慢,应尽量避免使用。

常见问题解答

  • 为什么 System.currentTimeMillis() 不适合测量代码运行时间?
    因为它在某些情况下会多次快速变化,导致计算结果出现误差。

  • System.nanoTime() 和 Stopwatch 有什么区别?
    Stopwatch 使用起来更方便,而 System.nanoTime() 精度更高。

  • 如何优化代码运行时间?
    减少不必要的循环、使用高效的数据结构和避免阻塞操作。

  • JMH 有什么优点?
    功能强大,可以更精确地测量代码运行时间。

  • 如何选择最合适的测量方法?
    考虑所需的精度、易用性和性能。