<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

利用StopWatch監控Java代碼運行時間和分析性能

Android編程精選 ? 來源:CSDN技術社區 ? 作者:獨淚了無痕 ? 2022-07-21 16:51 ? 次閱讀

利用StopWatch監控Java代碼運行時間和分析性能

一、背景

有時我們在做開發的時候需要記錄每個任務執行時間,或者記錄一段代碼執行時間,最簡單的方法就是打印當前時間與執行完時間的差值,一般我們檢測某段代碼執行的時間,都是以如下方式來進行的:

public static void main(String[] args) {  Long startTime = System.currentTimeMillis();  // 你的業務代碼  Long endTime = System.currentTimeMillis();  Long elapsedTime = (endTime - startTime) / 1000;  System.out.println("該段總共耗時:" + elapsedTime + "s");}

事實上該方法通過獲取執行完成時間與執行開始時間的差值得到程序的執行時間,簡單直接有效,但想必寫多了也是比較煩人的,尤其是碰到不可描述的代碼時,會更加的讓人忍不住多寫幾個bug聊表敬意,而且如果想對執行的時間做進一步控制,則需要在程序中很多地方修改。

此時會想是否有一個工具類,提供了這些方法,剛好可以滿足這種場景?

我們可以利用已有的工具類中的秒表,常見的秒表工具類

org.springframework.util.StopWatch、org.apache.commons.lang.time.StopWatch以及谷歌提供的guava中的秒表(這個我沒怎么用過)

這里重點講下基于spring、Apache的使用

二、spring 用法

2.1 初遇

StopWatch 是位于 org.springframework.util 包下的一個工具類,通過它可方便的對程序部分代碼進行計時(ms級別),適用于同步單線程代碼塊。簡單總結一句,Spring提供的計時器StopWatch對于秒、毫秒為單位方便計時的程序,尤其是單線程、順序執行程序的時間特性的統計輸出支持比較好。

也就是說假如我們手里面有幾個在順序上前后執行的幾個任務,而且我們比較關心幾個任務分別執行的時間占用狀況,希望能夠形成一個不太復雜的日志輸出,StopWatch提供了這樣的功能。而且Spring的StopWatch基本上也就是僅僅為了這樣的功能而實現。

想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,當然 Spring MVC 和 Spring Boot 都已經自動引入了該包:

    org.springframework    spring-core    ${spring.version}

對一切事物的認知,都是從使用開始,那就先來看看它的用法,會如下所示:

public static void main(String[] args) throws InterruptedException {    StopWatch stopWatch = new StopWatch();
    // 任務一模擬休眠3秒鐘    stopWatch.start("TaskOneName");    Thread.sleep(1000 * 3);    System.out.println("當前任務名稱:" + stopWatch.currentTaskName());    stopWatch.stop();
    // 任務一模擬休眠10秒鐘    stopWatch.start("TaskTwoName");    Thread.sleep(1000 * 10);    System.out.println("當前任務名稱:" + stopWatch.currentTaskName());    stopWatch.stop();
    // 任務一模擬休眠10秒鐘    stopWatch.start("TaskThreeName");    Thread.sleep(1000 * 10);    System.out.println("當前任務名稱:" + stopWatch.currentTaskName());    stopWatch.stop();
    // 打印出耗時    System.out.println(stopWatch.prettyPrint());    System.out.println(stopWatch.shortSummary());    // stop后它的值為null    System.out.println(stopWatch.currentTaskName()); 
    // 最后一個任務的相關信息    System.out.println(stopWatch.getLastTaskName());    System.out.println(stopWatch.getLastTaskInfo());
    // 任務總的耗時  如果你想獲取到每個任務詳情(包括它的任務名、耗時等等)可使用    System.out.println("所有任務總耗時:" + sw.getTotalTimeMillis());    System.out.println("任務總數:" + sw.getTaskCount());    System.out.println("所有任務詳情:" + sw.getTaskInfo());}

如圖所示,StopWatch 不僅正確記錄了上個任務的執行時間,并且在最后還可以給出精確的任務執行時間(納秒級別)和耗時占比,這或許就會比我們自己輸出要優雅那么一些。

2.2 源碼

老規矩,由淺入深??赐暧梅?,我們來看看源碼。先看下組成 StopWatch 的屬性

public class StopWatch {    /**  * 本實例的唯一 Id,用于在日志或控制臺輸出時區分的。  */    private final String id;    /**  * 是否保持一個 taskList 鏈表  * 每次停止計時時,會將當前任務放入這個鏈表,用以記錄任務鏈路和計時分析  */ private boolean keepTaskList = true;   /**  * 任務鏈表  * 用來存儲每個task的信息, taskInfo由taskName 和 totoalTime組成  */    private final List taskList;    /**  * 當前任務的開始時間  */    private long startTimeMillis;    /**  *   */    private boolean running;    /**  * 當前任務名稱  */    private String currentTaskName;    /**  * 最后一個任務的信息  */    private StopWatch.TaskInfo lastTaskInfo;    /**  * 任務總數  */    private int taskCount;    /**  * 程序執行時間  */    private long totalTimeMillis;    ...}

		
接下來,我們看一下StopWatch類的構造器和一些關鍵方法

089914ba-0758-11ed-ba43-dac502259ad0.png

2.3 注意事項

  • StopWatch對象不是設計為線程安全的,并且不使用同步。
  • 一個StopWatch實例一次只能開啟一個task,不能同時start多個task
  • 在該task還沒stop之前不能start一個新的task,必須在該task stop之后才能開啟新的task
  • 若要一次開啟多個,需要new不同的StopWatch實例

三、apache 用法

StopWath是 apache commons lang3 包下的一個任務執行時間監視器,與我們平時常用的秒表的行為比較類似,我們先看一下其中的一些重要方法:

08a97ee0-0758-11ed-ba43-dac502259ad0.png

    org.apache.commons    commons-lang3    3.6

		
Apache提供的這個任務執行監視器功能豐富強大,靈活性強,如下經典實用案例:
public static void main(String[] args) throws InterruptedException {    //創建后立即start,常用    StopWatch watch = StopWatch.createStarted();
    // StopWatch watch = new StopWatch();    // watch.start();
    Thread.sleep(1000);    System.out.println(watch.getTime());    System.out.println("統計從開始到現在運行時間:" + watch.getTime() + "ms");
    Thread.sleep(1000);    watch.split();    System.out.println("從start到此刻為止的時間:" + watch.getTime());    System.out.println("從開始到第一個切入點運行時間:" + watch.getSplitTime());    Thread.sleep(1000);    watch.split();    System.out.println("從開始到第二個切入點運行時間:" + watch.getSplitTime());
    // 復位后, 重新計時    watch.reset();    watch.start();    Thread.sleep(1000);    System.out.println("重新開始后到當前運行時間是:" + watch.getTime());
    // 暫停 與 恢復    watch.suspend();    System.out.println("暫停2秒鐘");    Thread.sleep(2000);
    // 上面suspend,這里要想重新統計,需要恢復一下    watch.resume();    System.out.println("恢復后執行的時間是:" + watch.getTime());
    Thread.sleep(1000);    watch.stop();
    System.out.println("花費的時間》》" + watch.getTime() + "ms");    // 直接轉成s    System.out.println("花費的時間》》" + watch.getTime(TimeUnit.SECONDS) + "s");}

四、最后

很多時候,寫代碼也是一種藝術,而借助這種實用工具我就覺得藝術感更強些。希望我們能有追求更加美好事物的心,這點對于接納新知識特別重要。

此處推薦這個監視器來代替之前的的使用,能讓小伙伴們更加靈活的分析你的代碼。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2909

    瀏覽量

    103203
  • 代碼
    +關注

    關注

    30

    文章

    4575

    瀏覽量

    67135
  • spring
    +關注

    關注

    0

    文章

    333

    瀏覽量

    14191
  • Apache
    +關注

    關注

    0

    文章

    64

    瀏覽量

    12347

原文標題:求求你別再用 System.currentTimeMillis() 統計代碼耗時了,真的太 Low 了!

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何縮短Vivado的運行時間

    在Vivado Implementation階段,有時是有必要分析一下什么原因導致運行時間(runtime)過長,從而找到一些方法來縮短運行時間。
    的頭像 發表于 05-29 14:37 ?1.4w次閱讀
    如何縮短Vivado的<b class='flag-5'>運行時間</b>

    stm32cubeIDE代碼運行時間如何查看?

    stm32cubeIDE 代碼運行時間,如何查看?就如 keil 調試時候那樣,可以測試代碼運行時間。但是在stm32cubeIDE 中,一直沒有找到這個功能,不知道哪位高人可以提示
    發表于 04-16 08:10

    freertos的任務運行時間怎么設置

    對于相同優先級的任務采用時間片輪詢的方式運行,那比如說有兩個優先級都為5的任務,那這兩個任務的運行時間如何設置呢?在rt-thread中創建任務時就可以設置任務的運行時間,在freer
    發表于 07-19 08:03

    請問6747如何測量代碼運行時間?

    1. 我想用片上的硬件定時器的方法測量代碼運行時間,使用timer,加頭文件:csl_timer.h,但是6747沒有csl,我下載了6747的cslr package,發現里面也沒有
    發表于 07-28 10:25

    C語言教程之顯示程序運行時間

    C語言教程之顯示程序運行時間,很好的C語言資料,快來學習吧。
    發表于 04-25 16:09 ?0次下載

    電機運行時間進行排列 是分為兩個部分來完成這個程序的設計的

    前幾天有個學員咨詢一個程序設計的問題,程序的控制要求如下:需要控制5臺電機的運行,每臺電機運行時需要記錄運行時間,電機啟動運行時,根據記錄的運行時間
    的頭像 發表于 07-19 08:57 ?6617次閱讀
    電機<b class='flag-5'>運行時間</b>進行排列 是分為兩個部分來完成這個程序的設計的

    如何高效測量ECU的運行時間

    ,最終可能會引起運行時間方面的問題。這在項目后期需要大量的時間和金錢來解決。如果不能掌握系統的運行狀態,則很難發現系統內缺陷的根源。 解決方案 將TA軟件工具套件與VX1000測量標定硬件相結合,可同步
    的頭像 發表于 10-28 11:05 ?1910次閱讀

    淺析STM32代碼運行時間的技巧

    前言 ????測試代碼運行時間的兩種方法: 使用單片機內部定時器,在待測程序段的開始啟動定時器,在待測程序段的結尾關閉定時器。為了測量的準確性,要進行多次測量,并進行平均取值。 借助示波器的方法
    的頭像 發表于 11-09 09:52 ?3441次閱讀
    淺析STM32<b class='flag-5'>代碼</b><b class='flag-5'>運行時間</b>的技巧

    了解如何讓您的汽車電池更穩定、運行時間更長

    了解如何讓您的汽車電池更穩定、運行時間更長
    發表于 11-01 08:27 ?0次下載
    了解如何讓您的汽車電池更穩定、<b class='flag-5'>運行時間</b>更長

    Go運行時:4年之后

    自 2018 年以來,Go GC,以及更廣泛的 Go 運行時,一直在穩步改進。近日,Go 社區總結了 4 年來 Go 運行時的一些重要變化。
    的頭像 發表于 11-30 16:21 ?576次閱讀

    AN021 測量MCU代碼運行時間的幾種方法

    AN021 測量MCU代碼運行時間的幾種方法
    發表于 02-27 18:23 ?0次下載
    AN021 測量MCU<b class='flag-5'>代碼</b><b class='flag-5'>運行時間</b>的幾種方法

    優化HBM2E運行時性能

    性能仍然是任何復雜片上系統 (SoC) 設計的關鍵因素。此外,復雜性每天都在增加,這給工程師跟蹤設計性能帶來了挑戰,但他們的任務是不斷提高芯片性能。在運行時,
    的頭像 發表于 05-26 10:17 ?451次閱讀
    優化HBM2E<b class='flag-5'>運行時</b><b class='flag-5'>性能</b>

    ch32v307記錄程序運行時間

    ,不僅會降低用戶的體驗,甚至可能會導致系統的崩潰。 因此,在程序設計和調試中,我們常常需要記錄程序的運行時間,并通過不斷的優化來提升程序的性能。本文將介紹如何在各種編程語言中記錄程序運行時間,并分享一些提高程序
    的頭像 發表于 08-22 15:53 ?535次閱讀

    如何在 CFD 設計中利用網格維護幾何形狀并減少運行時間?

    如何在 CFD 設計中利用網格維護幾何形狀并減少運行時間?
    的頭像 發表于 11-24 17:07 ?262次閱讀
    如何在 CFD 設計中<b class='flag-5'>利用</b>網格維護幾何形狀并減少<b class='flag-5'>運行時間</b>?

    jvm運行時內存區域劃分

    JVM是Java Virtual Machine(Java虛擬機)的縮寫,它是Java編程語言的運行環境。JVM的主要功能是將Java
    的頭像 發表于 12-05 14:08 ?291次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>