java计算程序运行耗时的方法

本文介绍了四种在Java中测量代码执行时间的方法,包括使用`System.currentTimeMillis()`、`java.time.Duration`、ApacheCommonsLang3的`StopWatch`以及Spring框架的`StopWatch`,并展示了它们的用法和特点。

有时候为了统计性能耗时,会写几行代码计算一个方法或者sql执行消耗多久时间,打印出日志分析。下面写了3种计算代码执行完所消耗时间的方法。 (对于一些重要的业务场景需要监控的,可以把这个耗时结果写入数据量通过job去告警)

package com.walmart.aloha.paperless;

import org.apache.commons.lang3.time.StopWatch;
import org.springframework.util.StopWatch;

import java.time.Duration;
import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * author yulisao
 * createDate 2023/9/11
 */
public class Test {

    public static void main(String[] args) throws InterruptedException {
        /**
         * 1 通用方法
         * 结束时间减去开始时间得到时间差 单位是毫秒 其他单位(比如秒、分、时等)需要自己去做除法运算转换
         */
        long beg = System.currentTimeMillis();
        Thread.sleep(1000); // 用休眠代替你的业务逻辑执行完时间
        long end = System.currentTimeMillis();
        System.out.println("消耗时间:" + (end-beg)); // 1000

        /**
         * 2 Duration用户(jdk1.8可使用,java.time包下的类)
         * 与上面写法类似 但时间差的单位不需要我们自己去作除法转换了,提供了对应的方案直接获取秒 还是 小时 ...
         */
        Instant beg1 = Instant.now();
        Thread.sleep(1000);
        Instant end1 = Instant.now();
        Duration duration = Duration.between(beg1, end1);
        System.out.println("消耗时间:" + duration.toMillis()); // 1000
        System.out.println("消耗时间:" + duration.toMinutes()); // 0 1秒不足1分钟所以是0


        /**
         * 3 StopWatch
         * 第三方jar包提供: org.apache.commons commons-lang3
         */
        StopWatch watch = StopWatch.createStarted(); //创建后立即start,常用
        Thread.sleep(1000); // 比如第1个sql查询
        System.out.println("消耗时间:" + watch.getTime()); // 1000 默认毫秒
        System.out.println("消耗时间:" + watch.getTime(TimeUnit.SECONDS)); // 1 可以指定单位

        watch.reset(); // 重置 比如统计第2个sql查询耗时多久就不用重新创建一个StopWatch,直接在原基础上重置即可
        watch.start(); // 重置后必须使用start方法重新开始计时
        Thread.sleep(500);
        System.out.println("消耗时间:" + watch.getTime()); // 500

        watch.suspend(); //暂停
        Thread.sleep(6000); // 模拟第3个sql耗时, 暂停后的时间不计入
        watch.resume(); //上面suspend,想要继续统计了需要恢复一下
        Thread.sleep(400); // 模拟第4个sql耗时 恢复后的时间继续计入
        System.out.println("消耗时间:" + watch.getTime()); // 500 + 400 = 900  统计了第2和4个sql查询的总耗时
        watch.stop(); // 停止计时

        /**
         * 4 StopWatch
         * 第三方jar包提供: org.springframework spring-core
         */
        StopWatch sw = new StopWatch(UUID.randomUUID().toString()); // uuid作为计时器的名称

        sw.start("第1个sql查询"); // 被计时的任务名称
        Thread.sleep(1000); // 第1个sql查询
        System.out.println("当前任务名称:" + sw.currentTaskName());
        sw.stop();

        sw.start("第2个sql查询"); // 被计时的任务名称 // 一次只能start一个任务,若上面那个任务没stop则下面这个不能start
        Thread.sleep(1000); // 第2个sql查询
        System.out.println("当前任务名称:" + sw.currentTaskName());
        sw.stop();

        sw.start("第3个sql查询"); // 被计时的任务名称
        Thread.sleep(1000); // 第3个sql查询
        System.out.println("当前任务名称:" + sw.currentTaskName());
        sw.stop();

        // 分别统计了改方法种这3个sql各耗时多少
        System.out.println(sw.prettyPrint()); // 按 耗时 占比 任务名称 进行列表展示
        System.out.println("所有任务总耗时:" + sw.getTotalTimeMillis()); // 3000
        System.out.println("任务总数:" + sw.getTaskCount()); // 3

    }
}

<think>好的,我现在需要回答如何在Java计算程序的运行时间。用户已经提供了一些引用资料,我需要先仔细理解这些资料,然后整理出一个清晰的回答步骤。 首先,查看用户提供的引用内容。引用1到5都提到了使用System.currentTimeMillis()或者System.nanoTime()来获取时间戳,通过计算时间差来得到程序运行时间。引用4中的示例代码展示了如何用currentTimeMillis()在程序开始和结束时获取时间,然后相减得到运行时间。引用2也提到了这两种方法,并指出nanoTime()可能更精确,但依赖于操作系统。 接下来,我需要确定回答的结构。用户希望步骤清晰,所以应该分点说明不同的方法。可能需要比较两种方法的优缺点,比如currentTimeMillis()和nanoTime()的区别,以及它们适用的场景。 然后,注意用户要求的中文回答,同时需要正确使用LaTeX格式的数学表达式,但这个问题中可能用不到数学公式,不过代码部分要正确展示。根据系统级指令,代码块需要用反引号包裹,并标注语言为Java。 还需要生成相关问题。用户示例中的相关问题涉及性能分析、优化方法和应用场景,所以这里可能需要生成类似的问题,比如如何选择两种时间方法、不同场景下的使用建议、时间计算精度的影响因素等。 另外,引用资料中的示例代码都是Java,我需要确保提供的代码示例正确无误,并且符合用户引用的方法。例如,引用4中的代码是计算循环的运行时间,而引用2提到使用nanoTime()。 可能还需要注意一些细节,比如currentTimeMillis()返回的是当前时间的毫秒数,而nanoTime()返回的是纳秒级的相对时间,更适合测量时间段。同时,要提醒用户注意,在多线程或系统时间调整的情况下,currentTimeMillis()可能不准确,而nanoTime()通常更稳定。 最后,生成的问题应该覆盖用户可能关心的其他方面,比如时间计算的精度、不同方法的适用情况、如何处理多次测量等。 总结步骤: 1. 介绍使用System.currentTimeMillis()的方法,给出代码示例。 2. 介绍System.nanoTime()的方法,同样提供代码。 3. 比较两者的优缺点和使用场景。 4. 提醒注意事项,如多次测量取平均。 5. 生成相关问题。</think>在Java计算程序运行时间的实现方法主要分为以下两种方式: ### 一、使用System.currentTimeMillis()方法 ```java long startTime = System.currentTimeMillis(); // 记录开始时间 // 需要计时的代码段 int sum = 0; for(int i=0; i<1000000; i++){ sum += i; } long endTime = System.currentTimeMillis(); // 记录结束时间 System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); // 输出结果[^1][^4] ``` **特点**: - 精度为毫秒级(1/1000秒) - 返回自1970年1月1日以来的绝对时间 - 适用于需要统计真实时间消耗的场景[^2][^5] ### 二、使用System.nanoTime()方法 ```java long start = System.nanoTime(); // 获取纳秒级起始时间 // 需要计时的算法 StringBuilder sb = new StringBuilder(); for(int i=0; i<10000; i++){ sb.append(i); } long duration = System.nanoTime() - start; System.out.println("耗时:" + duration + "纳秒"); // 输出纳秒级耗时[^2] ``` **特点**: - 精度达到纳秒级(1/1,000,000,000秒) - 返回与系统时钟无关的计时器值 - 更适合测量短时间片段的相对时间差[^3] ### 三、方法对比与选择建议 | 方法 | 精度 | 适用场景 | 注意事项 | |---------------------|--------|----------------------------|--------------------------| | currentTimeMillis() | 毫秒级 | 长时间任务、需要日历时间的场景 | 系统时间修改会影响结果 | | nanoTime() | 纳秒级 | 短时间测量、性能调优 | 仅适用于测量时间间隔[^3] | ### 四、最佳实践建议 1. 对于关键代码段应进行多次测量取平均值 2. 测试前建议执行JVM预热(先运行被测代码若干次) 3. 使用try-finally确保时间记录的准确性: ```java long start = System.nanoTime(); try { // 被测代码 } finally { long time = System.nanoTime() - start; } ``` ### 五、注意事项 - 纳秒级时间值可能溢出(约292年循环一次) - 不同操作系统对nanoTime()的实现精度存在差异 - 虚拟机暂停(如GC)会影响测量结果[^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值