JAVA 五月 04, 2022

stopwatch优雅打印执行时间

文章字数 5.8k 阅读约需 5 mins. 阅读次数 0

stopwatch优雅打印执行时间

背景

在开发过程中, 有时需要记录一段代码的执行时间,或任务执行的时间.传统用法是在执行开始于结束各记录一次时间,两次时间相减就是执行时间.但这每次计算都需要设置两个变量放于首位.且随着业务改动,调整较大. 而目前有这么一类秒表工具类stopwatch.一次定义,多次使用. 提供者有spring-framework,apache与google.

简单方法

在业务开始与结束分别获取一次系统时间,并在最后两值相减获取执行时间,并按照自己的格式输出.


    public static void main(String[] args) throws InterruptedException {
        
        Long t1 = System.currentTimeMillis();
        // 业务模拟
        Thread.sleep(100);
        Long t2 = System.currentTimeMillis();
        System.out.println("A执行了" + (t2-t1) +"ms");


        Long t3 = System.currentTimeMillis();
        // 业务模拟
        Thread.sleep(100);
        Long t4 = System.currentTimeMillis();
        System.out.println("B执行了" + (t4-t3) +"ms");
     }

spring的stopwatch用法

在业务最开始创建stopwatch对象.

在不同的各个业务阶段调用start与stop方法来打上开始与结束时间标记.

在合适的地方打印业务的耗时与占比

import org.springframework.util.StopWatch;

public static void main(String[] args) throws InterruptedException {
        StopWatch stopwatch = new StopWatch();
        stopwatch.start("A");
        Map<String,Integer> params = new HashMap<>();
        Thread.sleep(100);
        stopwatch.stop();
        stopwatch.start("B");
        for (int i =0;i<1000;i++) {
            String salt = RandomUtil.randomString(10);
            String md5 = DigestUtils.md5Hex("" + salt).toUpperCase().substring(8, 24);
            Integer count = params.get(md5);
            if (count == null) count = 0;
            count ++;
            params.put(md5,count);
        }
        stopwatch.stop();
        stopwatch.start("C");
        params.entrySet().stream().filter(stringIntegerEntry -> stringIntegerEntry.getValue() > 1).collect(Collectors.toList());
        stopwatch.stop();
        System.out.println(stopwatch.prettyPrint());
    }

结果

StopWatch '': running time = 323037500 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
128886100  040%  A
126799900  039%  B
067351500  021%  C

更多方法

  • getLastTaskTimeMillis() 获取最后一个任务的耗时
  • getTotalTimeSeconds()获取总耗时秒,同时也有获取毫秒的方法;
  • prettyPrint()优雅的格式打印结果,表格形式;
  • shortSummary()返回简短的总耗时描述;
  • getTaskCount()返回统计时间任务的数量;
  • getLastTaskInfo().getTaskName()返回最后一个任务TaskInfo对象的名称;

apache的stopwatch用法

在业务最开始创建stopwatch对象.

在不同的各个业务阶段调用split来打上时间标记.

并紧接着输出开始到切点标记的运行时间.

public static void main(String[] args) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Map<String,Integer> params = new HashMap<>();
    Thread.sleep(100);
    stopWatch.split();
    System.out.println("统计从开始到第一个切入点运行时间:" + stopWatch.getSplitTime() + "ms");

    for (int i =0;i<1000;i++) {
        String salt = RandomUtil.randomString(10);
        String md5 = DigestUtils.md5Hex("" + salt).toUpperCase().substring(8, 24);
        Integer count = params.get(md5);
        if (count == null) count = 0;
        count ++;
        params.put(md5,count);
    }
    stopWatch.split();
    System.out.println("统计从开始到第二个切入点运行时间:" + stopWatch.getSplitTime() + "ms");

    params.entrySet().stream().filter(stringIntegerEntry -> stringIntegerEntry.getValue() > 1).collect(Collectors.toList());
    stopWatch.split();

    System.out.println("统计从开始到第三个切入点运行时间:" + stopWatch.getSplitTime() + "ms");
    stopWatch.stop();
}

执行结果

统计从开始到第一个切入点运行时间:102ms
统计从开始到第二个切入点运行时间:185ms
统计从开始到第三个切入点运行时间:259ms

guava的stopwatch用法

与其他两个不同,google的stopwatch创建使用的是createStarted静态类.在需要的时候创建.

切点的统计使用的是elapsed()方法,

存在reset()方法,但需要再次调用start才开始计时.

public static void main(String[] args) throws InterruptedException {
    Stopwatch stopwatch = Stopwatch.createStarted();

    Map<String,Integer> params = new HashMap<>();
    Thread.sleep(100);
    System.out.println("统计从开始到第一个切入点运行时间:" + stopwatch.elapsed() + "ms");

    for (int i =0;i<1000;i++) {
        String salt = RandomUtil.randomString(10);
        String md5 = DigestUtils.md5Hex("" + salt).toUpperCase().substring(8, 24);
        Integer count = params.get(md5);
        if (count == null) count = 0;
        count ++;
        params.put(md5,count);
    }
    System.out.println("统计从开始到第二个切入点运行时间:" + stopwatch.elapsed() + "ms");
    stopwatch.reset().start();
    params.entrySet().stream().filter(stringIntegerEntry -> stringIntegerEntry.getValue() > 1).collect(Collectors.toList());

    System.out.println("统计第三个业务运行时间:" + stopwatch.elapsed() + "ms");
}

结果

统计从开始到第一个切入点运行时间:PT0.1079573Sms
统计从开始到第二个切入点运行时间:PT0.1422942Sms
统计从开始到第三个切入点运行时间:PT0.0433762Sms    
0%