【发布时间】:2016-09-01 06:20:46
【问题描述】:
我的目标是编写一个框架来测量方法执行或事务时间以及处理测量结果,即存储、分析等。事务可能包括对外部系统的调用,同步或异步等待结果。
已经有一些关于该主题的问题,例如
- “How do I time a method's execution”
- “Measure execution time for a Java method”
- “System.currentTimeMillis vs System.nanoTime”
所有的答案都归结为三种花时间的方法
System.currentTimeMillis()System.nanoTime()-
Instant.now()和Duration(Java 8 起)
我知道,所有这些都有一些含义
System.currentTimeMillis()
此方法的结果取决于平台。在 Linux 上,分辨率为 1 毫秒,在 Windows 上,分辨率为 10 毫秒(单核)~15 毫秒(多核)。因此,可以测量大型运行操作或短期运行操作的多次执行。
System.nanoTime()
你得到一个高分辨率的时间测量,具有纳秒精度(但不一定是纳秒精度),你会在 292 年后出现溢出(我可以忍受)。
Instant.now() 和持续时间
从 Java 8 开始有了新的时间 API。瞬间有一个秒和一个纳秒字段,因此它在对象引用的顶部使用两个长值(Duration 相同)。您还可以获得纳秒精度,具体取决于底层时钟(请参阅“Java 8 Instant.now() with nanosecond resolution?”)。实例化是通过调用Instant.now() 来完成的,该System.currentTimeMillis() 映射到正常系统时钟的System.currentTimeMillis()。
鉴于事实,很明显,只有使用 System.nanoTime() 才能实现最佳精度,但我的问题更多地针对处理一般措施的最佳实践,这不仅包括采取措施,也包括措施处理。
-
Instant 和 Duration 提供最佳 API 支持(计算、比较等),但在标准情况下具有依赖于操作系统的精度,并且内存和创建度量的开销更大(对象构造、更深的调用堆栈)
System.nanoTime() 和 System.currentTimeMillis() 具有不同级别的精度,但仅具有基本的“api”支持(长时间的数学运算),但获取速度更快,内存更小。
那么最好的方法是什么?有什么我没有想到的影响吗?有其他选择吗?
【问题讨论】:
-
写得很好,但可能太宽泛了...我的两分钱:没有,使用JodaTime。
-
根据 joda.org:“请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。” 是的,Joda 是第一个在 Java 中使用适当时间 API 的人,但据我所知,新的“官方”API 在大多数情况下都差不多,并且可能更可取。
-
System.nanotime 可能是您的最佳选择(它至少与其他两个选项一样精确,可能更精确,具体取决于 OS/CPU/JVM)。如果您需要进行一些计算,您可以随时从 nanos 创建 Duration。
-
@JordiCastilla 仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle。 Joda-Time 和 java.time 都由同一个人领导,Stephen Colebourne。对于 Java 6 和 7,大部分 java.time 功能都可以在 ThreeTen-Backport 项目中找到。
标签: java performance time java-8 timing