如何统计程序运行时间?

在我们日常工作中,一般怎么计算一段代码的耗时?
System.currentTimeMillis(),相信大家不陌生,还有一种就是StopWatch

一、System.currentTimeMillis()

1、使用

  • 记录开始时间
  • 记录结束时间
  • 计算两者差值

2、代码实现

public static void statisticsTime() throws InterruptedException {
	long start;
	long end;

	start = System.currentTimeMillis();
	Thread.sleep(300);
	end = System.currentTimeMillis();
	System.out.println("测试睡眠1耗时:" + (end - start) + "ms");

	start = System.currentTimeMillis();
	Thread.sleep(200);
	end = System.currentTimeMillis();
	System.out.println("测试睡眠2耗时:" + (end - start) + "ms");

	start = System.currentTimeMillis();
	Thread.sleep(1000);
	end = System.currentTimeMillis();
	System.out.println("测试睡眠3耗时:" + (end - start) + "ms");

}

3、运行结果

测试睡眠1耗时:302ms
测试睡眠2耗时:201ms
测试睡眠3耗时:1000ms

二、StopWatch

一个计时工具类,有很多个,这里使用的是org.springframework.util包下的StopWatch

1、使用

通过创建StopWatch,然后调用start方法和stop方法来记录时间,最后通过prettyPrint打印出统计分析信息。

2、代码实现

public static void statisticsTimeByStopWatch() throws InterruptedException {
	StopWatch stopWatch = new StopWatch("测试");

	stopWatch.start("测试睡眠1");
	Thread.sleep(300);
	stopWatch.stop();

	stopWatch.start("测试睡眠2");
	Thread.sleep(200);
	stopWatch.stop();

	stopWatch.start("测试睡眠3");
	Thread.sleep(1000);
	stopWatch.stop();

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

3、运行结果

StopWatch '测试': running time (millis) = 1521
-----------------------------------------
ms     %     Task name
-----------------------------------------
00300  020%  测试睡眠1
00221  015%  测试睡眠2
01000  066%  测试睡眠3

可以直观看到总的耗时,以及各种组成部分的耗时,很方便

三、Debug+StopWatch

无论你用前面哪种方法,都会发生代码侵入,那有没有一种方式,可以不修改我们的代码?
一般在我们调试代码,都会用到debug,这里就可以配置debug来实现,主要使用的是断点里面的“Evaluate and log”

1、自定义工具类

public class StopWatchUtils {

	private static StopWatch stopWatch;

	public static void init(String name) {
		stopWatch = new StopWatch(name);
	}

	public static String start(String name) {
		stopWatch.start(name);
		return "Task name: " + name + " start " + System.currentTimeMillis();
	}

	public static void stop() {
		stopWatch.stop();
	}

	/**
	 * 参考StopWatch.prettyPrint的代码
	 */
	public static String print() {
		StringBuilder sb = new StringBuilder("StopWatch '" + stopWatch.getId() + "': running time (millis) = " + stopWatch.getTotalTimeMillis());
		sb.append('\n');
		sb.append("-----------------------------------------\n");
		sb.append("ms     %     Task name\n");
		sb.append("-----------------------------------------\n");
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMinimumIntegerDigits(5);
		nf.setGroupingUsed(false);
		NumberFormat pf = NumberFormat.getPercentInstance();
		pf.setMinimumIntegerDigits(3);
		pf.setGroupingUsed(false);
		StopWatch.TaskInfo[] var4 = stopWatch.getTaskInfo();
		int var5 = var4.length;

		for (int var6 = 0; var6 < var5; ++var6) {
			StopWatch.TaskInfo task = var4[var6];
			sb.append(nf.format(task.getTimeMillis())).append("  ");
			sb.append(pf.format(task.getTimeSeconds() / ((double) stopWatch.getTotalTimeMillis() / 1000.0D))).append("  ");
			sb.append(task.getTaskName()).append("\n");
		}

		return sb.toString();
	}
}

2、打断点,设置打印的日志

断点一般是红色,这里的断点是黄色,是因为我们不想阻塞式运行,取消勾选了“Suspend”
断点示意图
1、设置第1个断点,初始化StopWatch,开始监控
设置第1个断点
2、设置第2个断点
设置第2个断点
3、设置第3个断点
设置第3个断点
4、设置第4个断点,结束,打印我们自定义的信息
设置第4个断点

3、运行结果

Task name: 测试睡眠1 start 1676858996740
Task name: 测试睡眠2 start 1676858997048
Task name: 测试睡眠3 start 1676858997249
StopWatch '测试': running time (millis) = 1508
-----------------------------------------
ms     %     Task name
-----------------------------------------
00301  020%  测试睡眠1
00201  013%  测试睡眠2
01006  067%  测试睡眠3

总结

通过上面的代码演示已经运行结果,比较后我们可以发现

  • System.currentTimeMillis使用简单,但统计结果不直观,代码入侵
  • StopWatch需要导入包,统计结果直观,但代码入侵
  • Debug+StopWatch,方便调试,统计结果直观
posted @ 2022-06-15 15:53  程序员Forlan  阅读(152)  评论(0编辑  收藏  举报