如何将StopWatch记录的代码时长转double并计算最小/最大/平均/中位值
实现方式
你所使用的StopWatch(无论是Apache Commons Lang版本还是Spring Framework版本)都提供了直接获取耗时数值的API,无需保留整个StopWatch实例做后续转换:
直接转换现有StopWatch集合的实现
通过Stream流可快速完成数值转换与统计,无需单独生成新的List即可拿到所需的所有统计值:
// 以毫秒为单位统计 DoubleSummaryStatistics statistics = list.stream() // Apache Commons用getTime(),Spring版本用getTotalTimeMillis() .mapToDouble(stopWatch -> (double) stopWatch.getTime()) .summaryStatistics(); double minMs = statistics.getMin(); double maxMs = statistics.getMax(); double avgMs = statistics.getAverage(); long totalCount = statistics.getCount(); // 单独计算中位值 List<Double> sortedDuration = list.stream() .map(sw -> (double) sw.getTime()) .sorted() .toList(); double medianMs; int size = sortedDuration.size(); if (size % 2 == 0) { medianMs = (sortedDuration.get(size / 2 - 1) + sortedDuration.get(size / 2)) / 2.0; } else { medianMs = sortedDuration.get(size / 2); }
更优的解决方案
你当前的实现有不必要的内存开销,无需存储整个StopWatch对象,直接存储耗时数值即可:
- 初始化时直接创建存储耗时的集合,避免后续转换开销:
// 需要更高精度时可以用List<Long>存储纳秒数值 List<Long> durationMsList = new ArrayList<>();
- 每次计时逻辑调整为:
StopWatch stopWatch = StopWatch.createStarted(); // 待测试的业务代码 stopWatch.stop(); // 直接存储耗时数值,无需保留StopWatch对象 durationMsList.add(stopWatch.getTime());
- 如果你是做性能基准测试,推荐直接使用JMH(Java Microbenchmark Harness),工具本身已内置预热、死代码消除规避、百分位统计、方差计算等专业能力,无需自己手动实现统计逻辑,结果准确性远高于手动计时。
注意事项
- 如果使用Spring StopWatch,将上述代码中的
getTime()替换为getTotalTimeMillis()即可,纳秒精度对应替换为getTotalTimeNanos()。 - 对精度要求极高的场景,避免用double存储长耗时的纳秒数值,可改用BigDecimal做统计避免精度丢失。
内容的提问来源于stack exchange,提问作者ness
相关产品推荐
相关产品推荐

