如何测量 Java 中经过的时间?
我想要这样的东西:
public class Stream
{
public startTime;
public endTime;
public getDuration()
{
return startTime - endTime;
}
}
同样重要的是,例如,如果开始时间是23:00,而结束时间是1:00,以获得2:00的持续时间。
为了在Java中实现此目的,使用哪种类型?
我想要这样的东西:
public class Stream
{
public startTime;
public endTime;
public getDuration()
{
return startTime - endTime;
}
}
同样重要的是,例如,如果开始时间是23:00,而结束时间是1:00,以获得2:00的持续时间。
为了在Java中实现此目的,使用哪种类型?
不幸的是,到目前为止发布的十个答案中没有一个是完全正确的。
如果要测量经过的时间,并且希望它是正确的,则必须使用 。你不能使用 ,除非你不介意你的结果是错误的。System.nanoTime()
System.currentTimeMillis()
的目的是测量经过的时间,其目的是测量挂钟时间。您不能将一个用于其他目的。原因是没有一台计算机的时钟是完美的;它总是漂移,偶尔需要纠正。这种校正可能是手动进行的,或者在大多数机器的情况下,有一个进程运行并不断对系统时钟(“挂钟”)发出小的校正。这些往往经常发生。每当有闰秒时,就会发生另一次这样的修正。nanoTime
currentTimeMillis
由于 的目的是测量经过的时间,因此它不受任何这些小修正的影响。这是你想要使用的。目前正在进行的任何时间都将关闭 - 甚至可能是负面的。nanoTime
currentTimeMillis
你可能会说,“这听起来好像真的没有那么重要”,对此我说,也许不是,但总的来说,正确的代码不是比不正确的代码好吗?此外,无论如何都要打字更短。nanoTime
以前发布的关于通常只有微秒精度的免责声明是有效的。此外,调用可能需要超过整整一微秒的时间,具体取决于情况(另一个情况也是如此),因此不要期望正确计算非常非常小的时间间隔。nanoTime
为了在Java中实现此目的,使用哪种类型?
简短的答案是.现在,更多关于如何测量...long
这样做的“传统”方法确实是使用System.currentTimeMillis()
:
long startTime = System.currentTimeMillis();
// ... do something ...
long estimatedTime = System.currentTimeMillis() - startTime;
请注意,Commons Lang 有一个 StopWatch 类,可用于以毫秒为单位测量执行时间。它具有诸如split()
,suspend()
,resume()
等方法方法,这些方法允许在执行的不同点采取措施,并且您可能会发现方便。看看它。
如果您正在寻找经过时间的极其精确的测量值,您可能更喜欢使用System.nanoTime()。
从它的javadoc:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
另一种选择是使用 JAMon,这是一个为 start() 和 stop() 方法之间的任何代码收集统计信息(执行时间、命中数、平均执行时间、最小值、最大值等)的工具。下面,一个非常简单的例子:
import com.jamonapi.*;
...
Monitor mon=MonitorFactory.start("myFirstMonitor");
...Code Being Timed...
mon.stop();
查看这篇关于 www.javaperformancetunning.com 的文章,了解一个很好的介绍。
最后,如果您不想用这些度量来混淆代码(或者如果您无法更改现有代码),那么AOP将是一个完美的武器。我不打算深入讨论这个问题,但我至少想提到它。
下面,使用AspectJ和JAMon的一个非常简单的方面(在这里,切点的短名称将用于JAMon监视器,因此调用):thisJoinPoint.toShortString()
public aspect MonitorAspect {
pointcut monitor() : execution(* *.ClassToMonitor.methodToMonitor(..));
Object arround() : monitor() {
Monitor monitor = MonitorFactory.start(thisJoinPoint.toShortString());
Object returnedObject = proceed();
monitor.stop();
return returnedObject;
}
}
可以很容易地调整切入点定义,以根据类名、包名、方法名或这些项的任意组合来监视任何方法。测量确实是AOP的完美用例。