这种方式更优雅,秒表计时
2014 年 2 月 19 日
你有看过学校百米赛跑时,体育老师手里的秒表吗?老师是怎么记八个跑道中的学生跑了多少时间的呢?
今天我们要做的就是实现老师手中的秒表,但是我们是没有办法同时跑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 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!