首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 程式執行時間精確測量:毫秒級 vs 納秒級 API 對比

     編輯:Java 相關知識

兩大核心 API

方法返回值精度用途注意事項
System.currentTimeMillis()long (ms)毫秒 (實際精度依 OS,通常 10-15ms)壁鐘時間、日期時間、長耗時任務、日誌時間戳受系統時間調整影響 (NTP 同步、用戶修改)
System.nanoTime()long (ns)納秒 (單調時鐘,高精度)效能基準測試、微基準、相對時間間隔測量無絕對意義,僅相對差值有效;不可跨 JVM 比較

標準測量範本

毫秒級 (適合 >10ms 任務)


long start = System.currentTimeMillis();
// doSomething();
long end = System.currentTimeMillis();
System.out.println("耗時: " + (end - start) + " ms");

納秒級 (適合微基準、熱點方法)


long start = System.nanoTime();
// doSomething();
long end = System.nanoTime();
System.out.println("耗時: " + (end - start) + " ns");
System.out.println("耗時: " + (end - start) / 1_000_000.0 + " ms");

進階:JMH (Java Microbenchmark Harness)

手工測量存在 JIT 預熱、死碼消除、編譯器優化干擾等陷阱。**生產級微基準必須用 JMH** (OpenJDK 官方工具)。


@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(2)
@State(Scope.Benchmark)
public class MyBenchmark {
    @Benchmark
    public void testMethod() {
        // 被測代碼
    }
}
  • 自動處理預熱、測量迭代、Fork 隔離、結果統計 (平均、中位數、百分位)。
  • Maven: org.openjdk.jmh:jmh-core + jmh-generator-annprocess。

JUnit 4/5 內建計時


// JUnit 4
@Test(timeout = 1000) // 超時失敗
public void test() { ... }

// JUnit 5 (Jupiter)
@Test
void test() {
    Assertions.assertTimeout(Duration.ofMillis(500), () -> { ... });
}

僅適用於**超時保護**,不提供精確耗時統計。

常見誤區

  1. 用 currentTimeMillis() 測微秒級代碼:精度不足,結果多為 0 或波動極大。
  2. 忽略 JIT 預熱:首次執行解釋模式,後續編譯優化,必須預熱後再測。
  3. 死碼消除:結果未被使用,JIT 可能直接刪除代碼。用 Blackhole.consume() (JMH) 或打印結果防止。
  4. 跨線程/跨進程比較 nanoTime():不同 JVM 實例、不同機器的納秒基準無關聯性。

總結建議

  • 業務日誌、慢查詢閾值、定時任務:currentTimeMillis() / Instant.now()。
  • 方法級效能優化、演算法對比、鎖爭用分析:nanoTime() + 多次迭代取中位數。
  • 發佈級基準報告、庫選型決策:**JMH**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved