阅读原文:这种方式更优雅,秒表计时!
你有看过学校百米赛跑时,体育老师手里的秒表吗?老师是怎么记八个跑道中的学生跑了多少时间的呢?
今天我们要做的就是实现老师手中的秒表, 但是我们计算机无法真正同时跑 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);
}
}
看完这段代码就问你,烦不烦?
问题所在
那么我们烦在哪里?
- 每次都要获取获取时间代码
- 每次都要主动打印
- 无关紧要的计时打印代码占据了视线
- 如果 n 段代码统计对比,需要人工对比或硬编码对比
好了,问题知道了,来想想解决方案吧。
解决方案
- 封装一个方法代替每次时间相减的代替
- 将打印最后统一输出
- 统计每段用时,排序或对比
开始实现我们的秒表类 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!