簡體   English   中英

為什么 System.nanoTime() 比 System.currentTimeMillis() 慢(在性能上)?

[英]Why is System.nanoTime() way slower (in performance) than System.currentTimeMillis()?

今天我做了一個快速的基准測試來測試System.nanoTime()System.currentTimeMillis()速度性能:

long startTime = System.nanoTime();

for(int i = 0; i < 1000000; i++) {
  long test = System.nanoTime();
}

long endTime = System.nanoTime();

System.out.println("Total time: "+(endTime-startTime));

這是結果:

System.currentTimeMillis(): average of 12.7836022 / function call
System.nanoTime():          average of 34.6395674 / function call

為什么跑速差異這么大?

基准系統:

Java 1.7.0_25
Windows 8 64-bit
CPU: AMD FX-6100

這個 Oracle 博客

System.currentTimeMillis()是使用 GetSystemTimeAsFileTime 方法實現的,它本質上只是讀取 Windows 維護的低分辨率時間值。 讀取這個全局變量自然是非常快的——根據報告的信息大約需要 6 個周期。

System.nanoTime()是使用QueryPerformanceCounter/ QueryPerformanceFrequency API (如果可用,否則返回currentTimeMillis*10^6) QueryPerformanceCounter(QPC)以不同的方式實現,具體取決於它運行的硬件。 通常,它將使用可編程間隔計時器 (PIT)、ACPI 電源管理計時器 (PMT) 或 CPU 級時間戳計數器 (TSC)。 訪問 PIT/PMT 需要執行慢速 I/O 端口指令,因此 QPC 的執行時間為微秒級。 相比之下,讀取 TSC 大約需要 100 個時鍾周期(從芯片讀取 TSC 並將其轉換為基於工作頻率的時間值)。

也許這回答了這個問題。 這兩種方法使用不同數量的時鍾周期,從而導致后一種速度慢。

在該博客的結論部分進一步:

如果您對測量/計算經過時間感興趣,請始終使用 System.nanoTime()。 在大多數系統上,它會給出微秒量級的分辨率。 但請注意,在某些平台上執行此調用也可能需要微秒的時間。

大多數操作系統(您沒有提到您使用的是哪一個)都有一個內存計數器/時鍾,可提供毫秒精度(或接近該精度)。 對於納秒精度,大多數必須讀取硬件計數器。 與硬件通信比讀取內存中已有的值要慢。

可能只在 Windows 上是這種情況。 請參閱對類似問題的回答。

基本上, System.currentTimeMillis()只是讀取 Windows 維護的全局變量(這就是它具有低粒度的原因),而System.nanoTime()實際上必須進行 IO 操作。

你是在 Windows 上測量它,不是嗎。 我在 2008 年完成了這個練習。nanoTime 在 Windows 上比 currentTimeMillis 慢。 我記得,在 Linux 上,nanotime 比 currentTimeMillis 快,而且肯定比在 Windows 上快。

需要注意的重要一點是,如果您嘗試測量多個亞毫秒級操作的聚合,則必須使用 nanotime,就好像操作在不到 1/1000 秒的代碼中完成一樣,比較 currentTimeMillis 將顯示操作為瞬時的所以其中 1,000 個仍然是即時的。 您可能想要做的是使用 nanotime 然后四舍五入到最接近的毫秒,因此如果操作花費了 8000 納秒,它將被計為 1 毫秒,而不是 0。

您可能想要做的是使用 nanotime 然后四舍五入到最接近的毫秒,因此如果操作花費了 8000 納秒,它將被計為 1 毫秒,而不是 0。

算術說明:

8000 納秒等於 8 微秒等於 0.008 毫秒。 舍入會將其設為 0 毫秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM