成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

還在用new Date計算任務執行時間?強烈建議使用這個API!

開發 前端
在實踐過程中,我們經常需要記錄一個任務執行的耗時,這是評價代碼好壞,評測代碼性能,排查業務執行問題的重要操作。那么,你是如何來獲取并計算任務執行耗時的呢?通過new Date獲得時間進行換算?還是有更好的方案?

在實踐過程中,我們經常需要記錄一個任務執行的耗時,這是評價代碼好壞,評測代碼性能,排查業務執行問題的重要操作。那么,你是如何來獲取并計算任務執行耗時的呢?通過new Date獲得時間進行換算?還是有更好的方案?本文給你答案。

獲取任務耗時通常做法

獲取任務耗時,最簡單的方式就是打印當前時間與任務開始執行時間的差值,實例代碼如下:

  1.  @Test 
  2. public void testElapsedTimes() throws InterruptedException { 
  3.  long startTime = new Date().getTime(); 
  4.  
  5.  // do something 
  6.  Thread.sleep(1000); 
  7.  
  8.  System.out.println("執行耗時:" + (new Date().getTime() - startTime) + "ms"); 

上述方式實現簡單,邏輯也比較直觀。但如果執行大量測試,測試中還有不同的代碼邏輯塊,那么需要改動的地方就比較多。

改進做法

在上述代碼中,如果IDE安裝有代碼檢查工具,則會提示采用System.currentTimeMillis()來獲取時間,而不是new Date().getTime()的方式。

改造之后,實現代碼如下:

  1. @Test 
  2. public void testElapsedTimes1() throws InterruptedException { 
  3.  long startTime = System.currentTimeMillis(); 
  4.  
  5.  // do something 
  6.  Thread.sleep(1000); 
  7.  
  8.  System.out.println("執行耗時:" + (System.currentTimeMillis() - startTime) + "ms"); 

在這樣的場景下(無需獲取更多Date相關信息)也推薦使用System.currentTimeMillis()來獲取時間戳。至于為什么,看一下Date的源碼實現就知道了。

Date的構造方法:

  1. public Date() { 
  2.     this(System.currentTimeMillis()); 

Date在構造時,本質上也是先獲得了System.currentTimeMillis(),然后再初始化其他信息。既然我們只需要時間戳,那就沒必要再構建Date對象了。從性能層面來說,能優化則優化。

Spring的StopWatch

上述兩種方式雖然性能和寫法有所區別,但本質是一樣的。下面我們來講講Spring提供的StopWatch類,它不僅可實現上述功能,而且還可以做類似任務執行時間控制,也就是封裝了一個對開始時間、結束時間記錄操作的Java類。

先通過StopWatch類來實現一下上述功能:

  1.  @Test 
  2. public void testStopWatch() throws InterruptedException { 
  3.  StopWatch sw = new StopWatch(); 
  4.  
  5.  sw.start("開始執行業務"); 
  6.  // do something 
  7.  Thread.sleep(1000); 
  8.  sw.stop(); 
  9.  
  10.  System.out.println(sw.getTotalTimeMillis()); 

通過創建StopWatch對象,然后調用它的start、stop方法來區分執行任務區間,通過getTotalTimeMillis()方法獲得總耗時。

乍一看,代碼好像還比之前的方式多了,體現不出來什么優勢啊!下面我們再來看一個復雜點的示例:

  1. @Test 
  2. ublic void testStopWatch1() throws InterruptedException { 
  3. StopWatch sw = new StopWatch(); 
  4.  
  5. sw.start("起床"); 
  6. Thread.sleep(1000); 
  7. sw.stop(); 
  8.  
  9. sw.start("洗漱"); 
  10. Thread.sleep(2000); 
  11. sw.stop(); 
  12.  
  13. sw.start("鎖門"); 
  14. Thread.sleep(500); 
  15. sw.stop(); 
  16.  
  17. System.out.println(sw.prettyPrint()); 
  18. System.out.println(sw.getTotalTimeMillis()); 
  19. System.out.println(sw.getLastTaskName()); 
  20. System.out.println(sw.getLastTaskInfo()); 
  21. System.out.println(sw.getTaskCount()); 

執行上述測試示例,打印結果如下:

  1. StopWatch '': running time = 3509166972 ns 
  2. --------------------------------------------- 
  3. ns         %     Task name 
  4. --------------------------------------------- 
  5. 1003330360  029%  起床 
  6. 2001421734  057%  洗漱 
  7. 504414878  014%  鎖門 
  8.  
  9. 3509 
  10. 鎖門 
  11. org.springframework.util.StopWatch$TaskInfo@12f40c25 

此時,看到StopWatch的魅力所在了嗎?

  • 通過多組start、stop方法,將業務代碼塊進行區分,可獲得不同代碼塊的執行耗時;
  • 可以通過start方法傳入taskName,對每個代碼塊進行命名;
  • 可以對總任務耗時、每個任務耗時進行統計分析;
  • prettyPrint()方法,可以優雅的打印出統計分析信息;
  • getTotalTimeMillis()方法,打印出總耗時;
  • getLastTaskName()方法,打印最后一個任務名稱;
  • getLastTaskInfo()方法,獲得最后一個任務的TaskInfo,進而獲得更多相關信息;
  • getTaskCount()方法,獲得任務數;

現在再看,使用StopWatch是不是可以獲得更多有用的信息?

StopWatch的實現原理

最后呢,我們再來看一眼源碼,了解一下StopWatch的實現機制。

先看StopWatch的start方法實現:

  1. public void start(String taskName) throws IllegalStateException { 
  2.  if (this.currentTaskName != null) { 
  3.   throw new IllegalStateException("Can't start StopWatch: it's already running"); 
  4.  } 
  5.  this.currentTaskName = taskName; 
  6.  this.startTimeNanos = System.nanoTime(); 

start方法中記錄了任務名稱和任務執行的時間,基于System.nanoTime()獲得。

stop方法實現如下:

  1. public void stop() throws IllegalStateException { 
  2.   if (this.currentTaskName == null) { 
  3.    throw new IllegalStateException("Can't stop StopWatch: it's not running"); 
  4.   } 
  5.   long lastTime = System.nanoTime() - this.startTimeNanos; 
  6.   this.totalTimeNanos += lastTime; 
  7.   this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime); 
  8.   if (this.keepTaskList) { 
  9.    this.taskList.add(this.lastTaskInfo); 
  10.   } 
  11.   ++this.taskCount; 
  12.   this.currentTaskName = null
  13.  } 

在stop方法中,通過兩個時間戳相減獲得lastTime,也就是一個任務的執行時間;lastTime累計相加獲得總的執行時間;同時,記錄任務列表、任務數統計。

而其他get方法,則是對start、stop中獲取的數據的進一步統計、分析、格式化輸出而已。

小結 

有些功能當我們使用習慣了,可能就固守于一個實現方式,但如果去參考學習其他框架中類似功能的實現,往往會有些新的突破。如果你在使用Spring的框架,建議你嘗試一下StopWatch這個API,可以讓你的時間統計日志更加高端大氣。

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2021-02-24 11:44:35

語言計算函數嵌入式系統

2018-07-18 15:13:56

MCU代碼時間

2023-05-25 19:23:29

2024-11-28 09:54:34

項目架構模型

2009-11-26 11:05:44

PHP計算頁面執行時間

2024-04-12 07:50:40

Python監控利器Time 模塊

2010-09-08 15:00:03

SQL語句執行

2021-03-02 07:13:54

Java8版本升級

2019-08-28 07:45:45

數據存儲層多線程

2010-04-28 12:33:36

Oracle自定義函數

2021-01-13 07:01:51

Adobe Flash Flash Playe

2023-01-27 15:28:04

開發Python內存

2011-05-17 13:32:04

oracle

2025-01-16 07:00:00

AOPSpringBoot后端

2021-01-05 05:36:08

Windows10操作系統Flash

2024-07-11 16:25:44

2011-08-25 09:17:24

庫克喬布斯蘋果

2021-09-27 10:52:06

React工具庫開發

2010-11-18 15:53:30

Oracle語句執行時

2010-09-06 13:17:19

SQL Server語句
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲欧美高清 | 一区二区三区精品 | 七七婷婷婷婷精品国产 | 中文字幕人成人 | 欧美视频成人 | 国产免费a视频 | 欧美第一区| 日韩三级免费观看 | 视频在线一区二区 | 中文字幕爱爱视频 | 亚洲成人毛片 | 国产欧美精品一区二区色综合 | 欧美日韩视频在线播放 | 台湾a级理论片在线观看 | 国产视频黄色 | 夜夜操av | 久久精品国产亚洲 | 亚洲国产成人精品女人久久久野战 | 成人亚洲| 欧美成人精品 | 国产精品视频久久久 | 国产精品日韩欧美一区二区三区 | 黄色片视频免费 | 亚洲午夜久久久 | 日韩图区| 久久久这里都是精品 | 在线播放亚洲 | 久久欧美高清二区三区 | 精品一区二区三区在线视频 | 男女视频在线观看免费 | 免费亚洲婷婷 | 伊人成人免费视频 | 99精品一区二区三区 | 91在线视频观看免费 | 成人性视频免费网站 | 国产在线视频一区二区 | 性一交一乱一透一a级 | 成人精品视频 | 玖玖玖在线 | 久久久婷 | 久久高清精品 |