自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

獲取任務耗時通常做法

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

  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("執(zhí)行耗時:" + (new Date().getTime() - startTime) + "ms"); 

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

改進做法

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

改造之后,實現(xiàn)代碼如下:

  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("執(zhí)行耗時:" + (System.currentTimeMillis() - startTime) + "ms"); 

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

Date的構造方法:

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

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

Spring的StopWatch

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

先通過StopWatch類來實現(xiàn)一下上述功能:

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

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

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

  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()); 

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

  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方法,將業(yè)務代碼塊進行區(qū)分,可獲得不同代碼塊的執(zhí)行耗時;
  • 可以通過start方法傳入taskName,對每個代碼塊進行命名;
  • 可以對總任務耗時、每個任務耗時進行統(tǒng)計分析;
  • prettyPrint()方法,可以優(yōu)雅的打印出統(tǒng)計分析信息;
  • getTotalTimeMillis()方法,打印出總耗時;
  • getLastTaskName()方法,打印最后一個任務名稱;
  • getLastTaskInfo()方法,獲得最后一個任務的TaskInfo,進而獲得更多相關信息;
  • getTaskCount()方法,獲得任務數(shù);

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

StopWatch的實現(xiàn)原理

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

先看StopWatch的start方法實現(xiàn):

  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方法中記錄了任務名稱和任務執(zhí)行的時間,基于System.nanoTime()獲得。

stop方法實現(xiàn)如下:

  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,也就是一個任務的執(zhí)行時間;lastTime累計相加獲得總的執(zhí)行時間;同時,記錄任務列表、任務數(shù)統(tǒng)計。

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

小結 

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

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

2021-02-24 11:44:35

語言計算函數(shù)嵌入式系統(tǒng)

2018-07-18 15:13:56

MCU代碼時間

2024-04-12 07:50:40

Python監(jiān)控利器Time 模塊

2009-11-26 11:05:44

PHP計算頁面執(zhí)行時間

2024-11-28 09:54:34

項目架構模型

2010-09-08 15:00:03

SQL語句執(zhí)行

2023-05-25 19:23:29

2019-08-28 07:45:45

數(shù)據(jù)存儲層多線程

2010-04-28 12:33:36

Oracle自定義函數(shù)

2011-05-17 13:32:04

oracle

2023-01-27 15:28:04

開發(fā)Python內(nèi)存

2025-01-16 07:00:00

AOPSpringBoot后端

2021-03-02 07:13:54

Java8版本升級

2021-01-13 07:01:51

Adobe Flash Flash Playe

2010-11-18 15:53:30

Oracle語句執(zhí)行時

2010-09-06 13:17:19

SQL Server語句

2011-08-25 09:17:24

庫克喬布斯蘋果

2021-09-27 10:52:06

React工具庫開發(fā)

2020-07-14 08:17:26

代碼執(zhí)行時間

2024-05-10 08:44:53

C#軟件開發(fā)優(yōu)化代碼
點贊
收藏

51CTO技術棧公眾號