我正在使用这段代码来测试哪种方法更快:
public void test() {
long start = System.currentTimeMillis();
MyDate date = new MyDate();
int max = 5000;
for (int i = 0; i < max; i++) {
Calendar.getInstance().getTimeInMillis(); // <--
}
System.out.println("Calendar instance delay: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < max; i++) {
date.getMillis(); // <--
}
System.out.println("My date delay: " + (System.currentTimeMillis() - start));
}
所以,基本上,我尝试来比较Calendar.getInstance().getTimeInMillis()
和MyDate.getMillis()
之间的效果(MyDate是我创建的一个类)。
好吧,当我运行上面的代码时,输出是:
Calendar instance delay: 413
My date delay: 2
但是,当我颠倒了订单(首先调用MyDate,并在日历之后)时,我得到了:
My date delay: 247
Calendar instance delay: 119
我尝试使用System.nanoTime()
,但同样的事情发生了:要测试的第一个代码是需要更长时间的代码。
任何人都知道为什么会出现这种差异?或者,有没有办法在不使用外部探查器应用程序(只是纯Java代码)的情况下准确地分析代码?
感谢。
答案 0 :(得分:4)
要测试“小”代码的性能,您必须多次调用它。否则,JIT,缓存和分支预测的影响会使测试变得混乱。如果我打电话给你,看看你回答之前需要多长时间,如果我几秒钟之前给你打电话,我会得到一个非常不同的答案。
答案 1 :(得分:1)
在commons lang中有使用System.nanoTime,
的StopWatch类http://commons.apache.org/lang/
org.apache.commons.lang.time.StopWatch
答案 2 :(得分:1)
在衡量性能时,请记住,JVM可能会消除作为优化的一部分没有副作用的代码。
为避免这种情况,您可以执行以下操作:
for (int i = 0; i < max; i++) {
long a = date.getMillis();
if (a % 1000 == i) {
System.out.print(a);
}
}
另一件需要注意的事情是热点优化。在测量之前,你应该“预热”你的代码。