記錄JAVA代碼執行耗時工具及示例


 
一、功能說明及效果展示
1. 支持多任務計時,每個子任務多段計時
2. 效果展示:
/** 
* 四種統計方案:
*  時間差統計
*  StopWatchTool
*  Function
*  AutoCloseable
*/
System:
 51
101
test StopWatchTool:
-----------------------------------------
taskName   taskChildName    ms 
-----------------------------------------
set : set  first  52  
get : get  first  51  

test Function:
-----------------------------------------
taskName   taskChildName    ms 
-----------------------------------------
set : set  first  50  second  50  
get : get  first  50  second  50  

test AutoCloseable:
-----------------------------------------
taskName   taskChildName    ms 
-----------------------------------------
set : set  first  51  second  52  
get : get  first  50  second  51 
二、實現方式
1. 計時工具:StopWatchTool
2. 包裝計時器:StopWatchHolder,為了支持function調用
 
三、測試代碼
/** 
* 四種統計方案:
*  時間差統計
*  StopWatchTool
*  Function
*  AutoCloseable
*/
public static void main(String[] args) throws InterruptedException {

    //時間差統計
    Long start = System.currentTimeMillis();

    Thread.sleep(50);

    Long end1 = System.currentTimeMillis();

    Thread.sleep(50);

    Long end2 = System.currentTimeMillis();

    System.out.println((end1 - start));
    System.out.println((end2 - start));

    //StopWatchTool
    StopWatchTool stopWatch = StopWatchTool.newInstance("test StopWatchTool");

    stopWatch.start("set", "first");
    Thread.sleep(50);

    stopWatch.stop();
    stopWatch.start("get", "first");

    Thread.sleep(50);

    stopWatch.stop();
    System.out.println(stopWatch.prettyPrint());

    //Function
    stopWatch = StopWatchTool.newInstance("test Function");

    StopWatchHolder.run(stopWatch, "set", "first", s -> {
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
    
    //同一個任務,兩段計時
    StopWatchHolder.run(stopWatch, "set", "second", s -> {
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
    });

    StopWatchHolder.run(stopWatch, "get", "first", g -> {
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
    
    //同一個任務,兩段計時
    StopWatchHolder.run(stopWatch, "get", "second", g -> {
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            e.printStackTrace();
        }
    });

    System.out.println(stopWatch.prettyPrint());

    //AutoCloseable
    stopWatch = StopWatchTool.newInstance("test AutoCloseable");

    try(StopWatchTool ignored = stopWatch.startByChain("set", "first")) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    try(StopWatchTool ignored = stopWatch.startByChain("set", "second")) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    try(StopWatchTool ignored = stopWatch.startByChain("get", "first")) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    try(StopWatchTool ignored = stopWatch.startByChain("get", "second")) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    System.out.println(stopWatch.prettyPrint());
}
四、源代碼
public class StopWatchHolder {

    /**
     * 有返回值調用
     */
    public static <T> T run(StopWatchTool stopWatch, String taskName, String taskChildName, Supplier<T> supplier) {
        try {
            stopWatch.start(taskName, taskChildName);

            return supplier.get();
        } finally {
            stopWatch.stop();
        }
    }

    /**
     * 無返回值調用
     */
    public static void run(StopWatchTool stopWatch, String taskName, String taskChildName, IntConsumer function) {
        try {
            stopWatch.start(taskName, taskChildName);

            function.accept(0);
        } finally {
            stopWatch.stop();
        }
    }
}
public class StopWatchTool implements AutoCloseable {

    /**
     * 任務ID
     */
    private String id;

    /**
     * Start time of the current task.
     */
    private long startMs;

    /**
     * Name of the current task.
     */
    @Nullable
    private String currentTaskName;

    /**
     * Second Name of the current task.
     */
    @Nullable
    private String currentTaskChildName;

    //記錄任務信息,同一任務,可以分段計時
    private final Map<String, List<TaskInfo>> taskMap = new HashMap<>();

    public static StopWatchTool newInstance(String id) {
        return new StopWatchTool(id);
    }

    @Override
    public void close() {
        this.stop();
    }


    public StopWatchTool(String id) {
        this.id = id;
    }

    /**
     * 開始時間差類型指標記錄,如果需要終止,請調用 {@link #stop()}
     *
     * @param taskName 指標名
     */
    public void start(String taskName, String taskChildName) throws IllegalStateException {
        if (this.currentTaskName != null) {
            throw new IllegalStateException("Can't start StopWatchTool: it's already running");
        }
        this.currentTaskName = taskName;
        this.currentTaskChildName = taskChildName;
        this.startMs = System.currentTimeMillis();
    }

    /**
     * 返回this,支持鏈式調用
     *
     * @param taskName
     * @return
     * @throws IllegalStateException
     */
    public StopWatchTool startByChain(String taskName, String taskChildName) throws IllegalStateException {
        if (this.currentTaskName != null) {
            throw new IllegalStateException("Can't start StopWatchTool: it's already running");
        }
        this.currentTaskName = taskName;
        this.currentTaskChildName = taskChildName;
        this.startMs = System.currentTimeMillis();

        return this;
    }

    /**
     * 終止時間差類型指標記錄,調用前請確保已經調用
     */
    public void stop() throws IllegalStateException {
        if (this.currentTaskName == null) {
            throw new IllegalStateException("Can't stop TraceWatch: it's not running");
        }
        long lastTime = System.currentTimeMillis() - this.startMs;

        TaskInfo info = new TaskInfo(this.currentTaskName, this.currentTaskChildName, lastTime);

        this.taskMap.computeIfAbsent(this.currentTaskName, e -> new LinkedList<>()).add(info);

        this.currentTaskName = null;
    }

    /**
     * 直接記錄指標數據,不局限於時間差類型
     *
     * @param taskName 指標名
     * @param data     指標數據
     */
    public void record(String taskName, String taskChildName, Object data) {

        TaskInfo info = new TaskInfo(taskName, taskChildName, data);

        this.taskMap.computeIfAbsent(taskName, e -> new LinkedList<>()).add(info);
    }

    /**
     * 打印
     *
     * @return
     */
    public String prettyPrint() {
        String whiteStr = "  ";
        StringBuilder sb = new StringBuilder(id).append(":").append("\n");

        if (this.taskMap.isEmpty()) {
            sb.append("No task info kept");
        } else {
            sb.append("-----------------------------------------\n");
            sb.append("taskName   taskChildName    ms \n");
            sb.append("-----------------------------------------\n");

            for (Map.Entry<String, List<TaskInfo>> entry : taskMap.entrySet()) {
                sb.append(entry.getKey());
                sb.append(" : ");
                for (int i = 0; i < entry.getValue().size(); i++) {
                    TaskInfo taskInfo = entry.getValue().get(i);
                    if (i == 0) {
                        sb.append(taskInfo.getTaskName()).append(whiteStr);
                    }
                    sb.append(taskInfo.getTaskChildName()).append(whiteStr);
                    sb.append(taskInfo.getData()).append(whiteStr);
                }
                sb.append("\n");
            }
        }

        return sb.toString();
    }


    /**
     * 任務信息
     */
    public static final class TaskInfo {

        private final String taskName;

        private final String taskChildName;

        private final Object data;

        public TaskInfo(String taskName, String taskChildName, Object data) {
            this.taskName = taskName;
            this.taskChildName = taskChildName;
            this.data = data;
        }

        public String getTaskName() {
            return taskName;
        }

        public String getTaskChildName() {
            return taskChildName;
        }

        public Object getData() {
            return data;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM