作者:捏造的信仰
來源:https://segmentfault.com/a/1190000041276485
Java有兩個取時間戳的方法:System.currentTimeMillis() 和 System.nanoTime(),它們的使用場景是有區別的,當前網上一些文章對于這兩個方法的性能討論存在一些片面的描述,本文希望能給出一個簡單的最終答案,
System.currentTimeMillis() 存在性能問題?
答案是否定的,這兩個方法性能差異取決于作業系統,
Windows:
在 Windows 下,System.currentTimeMillis() 比 System.nanoTime() 要快很多,這是因為 Windows 系統為前者提供的只是一個快取變數,而后者則是實時的去硬體底層獲取計數,
所以如果你的生產環境是 Windows,請盡可能避免使用
System.nanoTime(),
Linux:
在 Linux 下,兩者的執行耗時相差不大,不論是單執行緒還是多執行緒,
不同的虛擬機實作會帶來性能差異
如今的云主機主要有 Xen 和 KVM 兩種實作方式,網上有文章發現它們在取系統時間方面存在性能差異,
當你的虛擬機用的是 Xen 時,取時間的耗時會是 KVM 的十倍以上,不過上文也提供了遇到此類問題該如何解決的方案,
需要寫一個專門的類來提升 System.currentTimeMillis() 性能嗎?
不需要,那屬于畫蛇添足,
我的測驗代碼
我的測驗代碼如下,沒有任何依賴,可以直接用 javac 編譯然后運行,讀者有興趣可以試試:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class TimePerformance {
public static final int LOOP_COUNT = 9999999;
public static final int THREAD_COUNT = 30;
public static void main(String[] args) {
Runnable millisTest = () -> {
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
System.currentTimeMillis();
}
long end = System.currentTimeMillis();
System.out.printf("%s : %f ns per call\n",
Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
};
Runnable nanoTest = () -> {
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
System.nanoTime();
}
long end = System.currentTimeMillis();
System.out.printf("%s : %f ns per call\n",
Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
};
Consumer<Runnable> testing = test -> {
System.out.println("Single thread test:");
test.run();
System.out.println(THREAD_COUNT + " threads test:");
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < THREAD_COUNT; i++) {
Thread t = new Thread(test);
t.start();
threads.add(t);
}
// Wait for all threads to finish
threads.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
};
System.out.println("//// Test System.nanoTime()");
testing.accept(nanoTest);
System.out.println("//// Test System.currentTimeMillis()");
testing.accept(millisTest);
}
}
因為我用的是 Windows,所以執行輸出當中 System.nanoTime() 明顯非常慢,
具體輸出內容我就不放出來了,因為不具有參考價值,大多數生產環境用的是 Linux,
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
2.勁爆!Java 協程要來了,,,
3.Spring Boot 2.x 教程,太全了!
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/498490.html
標籤:Java
下一篇:Optional類詳解
