Java中不要使用System.currentTimeMillis()除錯測試延遲時間
System.currentTimeMillis()是所謂掛鐘概念:當前時間與 UTC 時間 1970 年 1 月 1 日午夜之間的差值(以毫秒為單位)。它只是告訴您當前系統時間是多少。並且使用它會導致很多問題:
1. 粒度
System.currentTimeMillis()以毫秒為單位返回當前時間,但值的粒度取決於底層作業系統,並且可能大於基本單位。例如,許多作業系統以幾十毫秒為單位測量時間。
假設您的作業系統以 100 毫秒為單位測量時間。在這種情況下,沒有辦法衡量需要比這更精確的任何東西。因此,如果某個操作需要 20 到 80 毫秒之間的某個時間,則您的測量結果為 0 或 100 毫秒(此精度可能會更差,例如:1 秒),更不用說測量亞毫秒級操作(微基準、奈米基準)。
2. 時間均勻性
您可能聽說過地球自轉存在不規則性(它以複雜的方式減慢和加速)。此外,地球自轉會長期放緩。有一個標準,稱為UT1(世界時的一個版本),它基於天文觀測和地球自轉。因此,UT1 並不總是均勻流動。因此,如果您的時間源基於此,則您有一個不均勻的時間源,它可以加速和減速,從而導致測量錯誤(請參閱:javadoc ofDate)。 System.currentTimeMillis()使用 UTC 而不是 UT1 所以它沒有這個確切的問題。
3. 閏秒
UTC是透過精確的原子鐘測量的,而UT1是基於天文觀測的(參見上一節)。為了使兩者保持一定程度的接近(<0.9 秒),UTC 偶爾會調整一秒。這種調整稱為閏秒。由於氣候和地質事件會影響地球的自轉,UTC 閏秒是不規則且不可預測的。這些調整可能會導致測量錯誤,因為在測量過程中時鐘可能會發生變化(請參閱:javadoc ofDate)。
4. 同步系統時鐘
當時鐘不以相同的速率執行時,可能會發生時鐘漂移(它們不同步)。為了讓它們彼此接近,時鐘同步是必要的(參見:NTP)。由於您的系統時鐘精度與原子鐘的精度相差甚遠,因此需要定期調整到UTC的幾毫秒內。這可能意味著時間跳躍或使時鐘走得更快或更慢,以便它會向 UTC 漂移。這些調整也會導致測量誤差。
5. 夏令時
如果夏令時在此類測量中引起問題,則需要真正搞砸一些事情,但如果您需要處理時間,則這是一個非常常見的問題。我見過一次服務每年崩潰兩次,你能猜到為什麼嗎?
解決方案:System.nanoTime()
解決方案非常簡單:不要使用“掛鐘”。在 Java 中:System.nanoTime()您可以訪問專為測量經過時間而設計的高解析度時間源(納秒),它與系統時鐘或任何“掛鐘”無關,請參閱 的javadocSystem.nanoTime()。所以你可以這樣做:
Response handleRequest(Request request) { long start = System.nanoTime(); try { return doSomething(request); } finally { record(System.nanoTime() - start); } } |
如果在做其他效能測試,建議:
- 如果你在做 (nano/micro/milli/macro) 基準測試:JMH
- 如果您想為您的應用程式收集指標:Micrometer
- 如果您想對您的 Web 服務進行效能測試:Gatling
相關文章
- 『開源』大半夜除錯TCP延遲問題除錯TCP
- 【每日一題】743. 網路延遲時間每日一題
- Android優化(三)_延遲電池續航時間Android優化
- 由system.currentTimeMillis() 獲得當前的時間
- Flink 鏈路延遲測量
- 新冠疫情致整體入睡時間延遲2到3小時
- 解決歷理 win11延遲系統更新時間
- Apache Pulsar 與 Kafka 效能比較:延遲性(測試方法)ApacheKafka
- 技術分享 | OceanBase 租戶延遲刪除
- ORACLE密碼錯誤驗證延遲Oracle密碼
- Python 之 錯誤,除錯和測試Python除錯
- dataguard主備延遲多長時間的2種查詢方法
- 打破延遲,實時同步不再難!
- goldengate抽取程式延遲90小時Go
- osg使用整理(11):延遲渲染
- PostgreSQL中的複製延遲SQL
- 時間線測試
- 痞子衡嵌入式:利用GPIO模組來測量i.MXRT1xxx的系統中斷延遲時間
- 使用httpstat測試網站響應時間HTTP網站
- 如何利用網路延遲穿越時空
- Netflix使用ZGC實現低延遲GC
- Python學習之錯誤除錯和測試Python除錯
- mysql之 誤用SECONDS_BEHIND_MASTER衡量MYSQL主備的延遲時間MySqlAST
- RabbitMQ延遲訊息的延遲極限是多少?MQ
- FCoE測試重啟除錯記錄除錯
- 延時 (遲) 操作的 PHP 簡單實現PHP
- JMeter定時器設定延遲與同步JMeter定時器
- 在寫 phpunit 測試的時候,千萬不要使用 PHP artisan config:cachePHP
- 使用RabbitMq原生實現延遲佇列MQ佇列
- 延遲繫結
- Java中使用JMX除錯簡介Java除錯
- EF中延遲載入的那些事
- Spring Boot 2.2 中的延遲載入Spring Boot
- [20150409]只讀表空間與延遲塊清除.txt
- Java程式中除錯Python程式方法Java除錯Python
- JSBridge通訊時間測試JS
- [譯] 從零開始,在 Redux 中構建時間旅行式除錯Redux除錯
- 定時器(setTimeout/setInterval)最小延遲的問題定時器