这种方式更优雅,秒表计时!

你有看过学校百米赛跑时,体育老师手里的秒表吗?老师是怎么记八个跑道中的学生跑了多少时间的呢?

今天我们要做的就是实现老师手中的秒表,但是我们是没有办法同时跑N个任务的,只能一个跑完继续下一个。

许多人统计用时会向下面这样,但方式并不优雅!现在我们来一起实现一个秒表让统计更加优雅吧。

public class Test{
    public static void main(String[] args) {
       long s =  System.currentTimeMillis();
       // 算法1
       // do something
       long s1 = System.currentTimeMillis() - s;
       System.out.println("第一段代码执行时间:"+s1);
       // 算法2
       // do something
       long s2 = System.currentTimeMillis() - s1;
       System.out.println("第二段代码执行时间:"+s2);
    }
}

看完这段代码就问你,烦不烦?

问题所在

那么我们烦在哪里?

1. 每次都要获取获取时间代码

2. 每次都要主动打印

3. 无关紧要的计时打印代码占据了视线

4. 如果n段代码统计对比,需要人工对比或硬编码对比

好了,问题知道了,来想想解决方案吧。

解决方案

1. 封装一个方法代替每次时间相减的代替

2. 将打印最后统一输出

3. 统计每段用时,排序或对比

开始实现我们的秒表类 StopWatch 吧

  • 每段计时任务要有一个唯一标识和一个最终用时

  • 需要一个容器来存储每个计时任务

  • 需要记录总时长和任务数量

具体实现

  • 每个计时任务类

public class Task {
        private String name;
        private long timeMillis;
        public Task(String name, long timeMillis) {
            this.name = name;
            this.timeMillis = timeMillis;
        }
}
  • 秒表类

public class StopWatch {
    /*
     * 存储执行或的任务容器
     */
    private List<Task> tasks = new ArrayList<>();  
    /*
     * 当前执行的任务
     */
    private String currentName; 
    /*
     * 当前任务的开始时间
     */
    private long startMillis;   
    /*
     * 总用时
     */
    private long totalMillis;  
    public StopWatch() {
    }
    /**
     * 开始任务
     * @param taskName 任务名
     */
    public void start(String taskName) {
        if (currentName != null){
            stop();
        }
        this.currentName = taskName;
        this.startMillis = System.currentTimeMillis();
    }
    /**
     * 停止任务
     */
    public void stop() {
        if (null == currentName) {
            throw new RuntimeException("");
        }
        long spend = System.currentTimeMillis() - startMillis;
        totalMillis += spend;
        Task task = new Task(currentName, spend);
        tasks.add(task);
    }
    public int size() {
        return tasks.size();
    }
    /**
     * 打印结果
     */
    public void print() {
        if (currentName != null){
            stop();
        }
        StringBuilder s = new StringBuilder();
        s.append("任务名称\t用时\t占比\t\n");
        for (Task task : tasks) {
            s.append(task.getName() + "\t");
            s.append(task.getTimeMillis() + "\t");
            double l = task.getTimeMillis() / (double)totalMillis;
            s.append(String.format("%.2f",l)  + "\t\n");
        }
        s.append("总用时:" + totalMillis);
        System.out.println(s.toString());
    }
}
  • 那么看看现在如何做

public class Test {
    public static void main(String[] args){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("任务1");
        TimeUnit.SECONDS.sleep(1);
        stopWatch.start("任务2");
        TimeUnit.SECONDS.sleep(2);
        stopWatch.print();
    }
}

此时我露出了满意的笑容!

最后告诉你个消息:Apache commons , Spring core , Google guava 都给我们实现了稍有不同的StopWatch类!

如果你跟随我一块实现了StopWatch,那去看看这三个提供的,应该 so easy!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值