最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)代碼塊耗時測算工具類

 更新時間:2023年05月22日 10:35:42   作者:BillySir  
這篇文章主要為大家介紹了如何利用Java語言編寫一個工具類,用來測算代碼塊的耗時,同時還能顯示進度,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

1. 測算耗時

背景

程序員經(jīng)常需要知道一段代碼的執(zhí)行耗時。典型的例如查詢數(shù)據(jù)庫,不同參數(shù)查詢到不同的數(shù)據(jù)量,耗時相差很大。如果一個操作總體耗時較大,包含了幾次數(shù)據(jù)庫操作,自然就想知道哪一次操作是長耗時的主要原因,甚至每一個的耗時是多少。從而可以有的放矢地做優(yōu)化。

使用要簡單

測算一段代碼的耗時,通常就是用stop watch(秒表)。在執(zhí)行的開始點開始計時,在執(zhí)行的結(jié)束點停止計時,并把耗時輸出到日志。雖然代碼也就幾行,但每個地方都這么寫,會顯得很啰嗦,編碼效率也低。

所以我把這個功能封裝成一個實用工具類。用起來大概是這樣子:

MonitorUtil.time(() -> {
    // 一個耗時操作,如查詢數(shù)據(jù)庫
}, "給這個操作起個名");

它會這樣輸出到日志:

[WARN] 2023-05-19T08:26:00.007 xx-project com.xxx.util.MonitorUtil 給這個操作起個名 elapsed 3,140 ms. warning

末尾的warning會在某些終端上顯示為黃色,顯眼。

輸出要簡潔

在線上運行時,也希望能知道耗時比較大的代碼。但如果每處測算耗時的地方都輸出日志,日志就會太多,而我們只關(guān)注那些長耗時。所以我規(guī)定:少于500毫秒的,不輸出。

暫停與繼續(xù)

有一種場景,在一個代碼范圍內(nèi),只期望計算一部分操作的累計耗時,而忽略其它操作的耗時。

比如,處理一批文件,每個文件要解析后將結(jié)果存為另一個文件。這里只關(guān)心解析的時間,而忽略寫文件的耗時。所以MonitorUtil提供了暫停和繼續(xù)的功能。在寫文件時,暫停計時,寫文件后開始解析另一個文件時繼續(xù)計時。

最終會輸出累計的耗時以及累計等待耗時。累計等待耗時,即是從暫停到繼續(xù)的時長的總和。

代碼:

MonitorUtil.time(monitor -> {
    for (...) {
        // 文件解析
        monitor.pause();
        // 其它操作
        monitor.continue();
    }
}, "僅算文件解析");

輸出如下:

[WARN] 2023-05-19T08:26:00.008 xx-project com.xxx.util.MonitorUtil 僅算文件解析 elapsed 1,140 ms,waited 2,000ms. warning
這樣就能知道那段代碼是工作的時間多還是等待的時間多了。

2. 顯示進度

說另一個問題,也是跟時間有關(guān)的。有些功能耗時比較長,比如循環(huán)處理數(shù)據(jù)?;蛟S是10秒,或許是10分鐘。對著沒有什么輸出的屏幕,顯得很無助。此時如果能知道剩下大概需要多少時間,無疑對做決策有大幫助。如,是中斷還是繼續(xù)等。

當(dāng)然了,進度百分比,只有業(yè)務(wù)代碼才知道。但業(yè)務(wù)代碼難以把握如何輸出這個進度。密了則輸出一大堆,干擾視線。疏了又是漫長無助的等待。所以,是由業(yè)務(wù)代碼報告進度,由這個工具決定要不要輸出。

代碼:

MonitorUtil.time(monitor -> {
    for (...) {
        // 一些操作
        monitor.process(proc);     // proc 是[0,1]區(qū)間的浮點數(shù),表示進度
    }
}, "給這個操作起個名");

要做到輸出不能太密,不能太疏。所以MonitorUtil內(nèi)部的規(guī)則如下:

  • 5秒內(nèi)不輸出兩次
  • 5~10秒,前進至少3%才輸出
  • 10~15秒,前進至少1%才輸出
  • 大于15秒,無論進度如何都輸出

這里說的多少秒,是相對于上一次輸出的時間而言。前進也是相對于上一次輸出。

輸出:

[INFO] 2023-05-19T08:26:00.009 xx-project com.xxx.util.MonitorUtil 給這個操作起個名 7% 30% 61% 98% 100%`

嵌套使用

假如有兩個進度測試的代碼嵌套在一起,如

MonitorUtil.time(monitor -> {
    for (...) {
        // 一些操作
        abc();
        // 一些操作
        monitor.process(proc);     // proc 是[0,1]區(qū)間的浮點數(shù),表示進度
    }
}, "大功能名");

void abc() {
    MonitorUtil.time(monitor -> {
        for (...) {
            // 一些操作
            monitor.process(proc);     // proc 是[0,1]區(qū)間的浮點數(shù),表示進度
        }
    }, "小功能名");
}

由于日志只有一份,兩個進度的輸出就會混在一起,很亂,看不清。所以解決這個問題,我規(guī)定當(dāng)發(fā)生進度測算嵌套時,只有最外層的有效,即只有最外層的會輸出。好像也沒有更好的辦法了,如果您有更好的建議,請留言。感謝。

3. 這個工具的優(yōu)勢

高性能

  • 它的輸出都是被動的。即只在被測代碼開始、結(jié)束、主動調(diào)用process方法時,才執(zhí)行邏輯,才有可能輸出。如果process方法沒有被調(diào)用,就算過了15秒,也不會有進度輸出。所以,在應(yīng)用的時候,可以偏頻繁一些地調(diào)用process方法。調(diào)了不一定有輸出,不調(diào)一定不會輸出。
  • 它的內(nèi)部是順序的判斷,沒有循環(huán),更沒有復(fù)雜算法,非常高效。
  • 它并沒有創(chuàng)建新的線程(單線程),而是與業(yè)務(wù)代碼工作在同一個線程。它消耗的資源非常少,包括內(nèi)存消耗很少。在除了“開始、結(jié)束、process方法被調(diào)用時”之外,消耗的CPU為零。用它來測算時間,成本極低,可以大量使用。

支持異常

業(yè)務(wù)代碼發(fā)生異常時,它還能不能測算出耗時?可以的?;卣{(diào)方法(lambda表達式)如果發(fā)生的異常,它也能計算耗時,并在耗時超過500毫秒時輸出。異常也是結(jié)束的一種。

測算的目標形式

如前面所見,它測算的目標形式是代碼塊,而代碼塊是最靈活的表現(xiàn)形式。它可以是一行代碼,可以是多行。可以是一個函數(shù)的完整代碼,也可以是函數(shù)的一部分代碼。

4. 實現(xiàn)原理簡介

它的內(nèi)部實現(xiàn)原理并不難。測算時間,就是記錄(用變量保存)開始時間,并在結(jié)束時計算一下時間差。進度功能,則是記錄上一次的輸出時間和進度,下次輸出時作對比。暫停功能,則是用兩個變量分別記錄工作和等待的耗時累加值。至于如何知道自己是不是“最外層”,則是用一個static變量來保存當(dāng)前的層數(shù)。如果是0就是最外層。

它的每一處實現(xiàn),都是平淡無奇。借用棋類的話,就是“通盤無妙手”。關(guān)鍵是實用。

到此這篇關(guān)于Java實現(xiàn)代碼塊耗時測算工具類的文章就介紹到這了,更多相關(guān)Java代碼耗時內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java程序包不存在的3種解決方法總結(jié)

    Java程序包不存在的3種解決方法總結(jié)

    包存在的,但是啟動項目的時候提示包不存在,所以解決下,這篇文章主要給大家介紹了關(guān)于Java程序包不存在的3種解決方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • SpringMVC的概念以及快速入門示例

    SpringMVC的概念以及快速入門示例

    這篇文章主要介紹了SpringMVC的概念以及快速入門示例,SpringMVC 已經(jīng)成為目前最主流的MVC框架之一,它通過一套注解,讓一個簡單的 Java 類成為處理請求的控制器,而無須實現(xiàn)任何接口,需要的朋友可以參考下
    2023-05-05
  • SpringBoot整合EasyExcel實現(xiàn)導(dǎo)入導(dǎo)出功能

    SpringBoot整合EasyExcel實現(xiàn)導(dǎo)入導(dǎo)出功能

    EasyExcel是一個基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具,他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能,本文就給大家介紹一下SpringBoot整合EasyExcel實現(xiàn)導(dǎo)入導(dǎo)出功能的方法,需要的朋友可以參考下
    2023-09-09
  • Java中的CopyOnWriteArrayList你了解嗎

    Java中的CopyOnWriteArrayList你了解嗎

    CopyOnWriteArrayList是Java集合框架中的一種線程安全的List實現(xiàn),這篇文章主要來和大家聊聊CopyOnWriteArrayList的簡單使用,需要的可以參考一下
    2023-06-06
  • mybatis批量插入,批量更新以及null值問題的解決

    mybatis批量插入,批量更新以及null值問題的解決

    這篇文章主要介紹了mybatis批量插入,批量更新以及null值問題的解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java 重試框架 Sisyphus 配置的兩種方式

    Java 重試框架 Sisyphus 配置的兩種方式

    這一節(jié)讓我們一起學(xué)習(xí)下 sisyphus 基于函數(shù)式的配置和注解式的配置。為了滿足更加方便的配置,Retryer 類提供了許多可以配置的信息。下面一起進入文章了解詳情內(nèi)容
    2021-11-11
  • Java中Arrays.asList()需要注意的坑

    Java中Arrays.asList()需要注意的坑

    在Java中,我們經(jīng)常需要將數(shù)組轉(zhuǎn)換為List來方便地進行操作,Arrays.asList()方法是一種常見的方式,本文主要介紹了Java中Arrays.asList()需要注意的坑,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Spring Bean作用域與生命周期全解析(推薦)

    Spring Bean作用域與生命周期全解析(推薦)

    Spring Bean作用域與生命周期詳解,涵蓋 Singleton、Prototype、Request、Session、Application 五種作用域,解析其特點、配置方式及適用場景,感興趣的朋友跟隨小編一起看看吧
    2026-05-05
  • Java與WebUploader相結(jié)合實現(xiàn)文件上傳功能(實例代碼)

    Java與WebUploader相結(jié)合實現(xiàn)文件上傳功能(實例代碼)

    這篇文章主要介紹了Java結(jié)合WebUploader實現(xiàn)文件上傳功能,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-03-03
  • java 設(shè)計模式之State(狀態(tài)模式)

    java 設(shè)計模式之State(狀態(tài)模式)

    這篇文章主要介紹了java 設(shè)計模式之State(狀態(tài)模式)的相關(guān)資料,一個類的行為基于它的狀態(tài)的改變而改變。狀態(tài)模式歸屬于行為型模式,需要的朋友可以參考下
    2017-08-08

最新評論

宣威市| 得荣县| 黔江区| 温宿县| 沙湾县| 仁寿县| 咸丰县| 五河县| 南川市| 宁蒗| 虞城县| 宜兰县| 江陵县| 张掖市| 平度市| 织金县| 盈江县| 毕节市| 哈尔滨市| 梧州市| 九江县| 开化县| 湛江市| 信宜市| 铁力市| 濉溪县| 清水县| 内乡县| 宜黄县| 台北市| 湄潭县| 玉林市| 灵石县| 仁寿县| 芷江| 永川市| 遵义市| 丹东市| 沭阳县| 新田县| 齐河县|