我回答this question并注意到在运行代码时引起我兴趣的东西。部分问题是关于各种风格的相同条件检查的表现,例如:
if (x > 0) {
if (y > 0) {
if (z > 0) {
if (complexCondition()) {
noOp();
}
}
}
}
与
if (x > 0 && y > 0 && z > 0 && complexCondition()) {
noOp();
}
我编写了一个程序,计算执行一定次数的迭代需要多长时间,结果是我不明白的结果。
这是我的程序在我的机器上的输出(Win 8.1 64位,javac 1.8.0_11(Oracle),java 1.0.0_11(Java SE,Oracle)。我已经多次运行每个试验并且它们可重复结果。
x = 9, y = 2, z = 8, countTrials = 1, iterationsPerTrial = 2736000
Method Average Runtime(ns)
guardIf() 5746173
multipleIf() 4868180
chainedIf() 9316172
x = 9, y = 2, z = 8, countTrials = 100, iterationsPerTrial = 2736000
guardIf() 1642750
multipleIf() 1121897
chainedIf() 1739522
x = -1, y = 2, z = 8, countTrials = 1, iterationsPerTrial = 2736000 // I expect shorter results with x = -1, because they all short curcuit
guardIf() 9245313
multipleIf() 8728608
chainedIf() 11718332
x = -1, y = 2, z = 8, countTrials = 100, iterationsPerTrial = 2736000
guardIf() 1754279
multipleIf() 1611278
chainedIf() 4947295
毫秒测量(用org.apache.commons.lang3.time.StopWatch
实现)
x = 9, y = 2, z = 8, countTrials = 1, iterationsPerTrial = Integer.MAX_VALUE
Method Average Runtime(ms)
guardIf() 1664
multipleIf() 1095
chainedIf() 1654
x = -1, y = 2, z = 8, countTrials = 1, iterationsPerTrial = Integer.MAX_VALUE
Method Average Runtime(ms)
guardIf() 4886
multipleIf() 4926
chainedIf() 4862
x = 9, y = 2, z = 8, countTrials = 10, iterationsPerTrial = Integer.MAX_VALUE
Method Average Runtime(ms)
guardIf() 1673
multipleIf() 1108
chainedIf() 1682
x = -1, y = 2, z = 8, countTrials = 10, iterationsPerTrial = Integer.MAX_VALUE
Method Average Runtime(ms)
guardIf() 4364
multipleIf() 4363
chainedIf() 4877
为什么所有方法的运行需要更长时间(在chainIf
的情况下,时间几乎多300%),当他们检查的值允许它们全部缩短时?
我已经使用调试器完成了所有这些操作,并且它们实际上做了一些简短的工作(正如我所期待的那样)。我检查了字节码,chainedIf()
和multipleIf()
完全相同。我很难过和好奇。
我不确定我的测量方式是否有一些缺陷,所以我在下面列出了我的程序。
计划来源
class TrialResult {
public long GuardIf = 0;
public long MultipleIf = 0;
public long ChainedIf = 0;
public TrialResult(long guardIf, long multipleIf, long chainedIf) {
this.GuardIf = guardIf;
this.MultipleIf = multipleIf;
this.ChainedIf = chainedIf;
}
}
public class Program {
private int x;
private int y;
private int z;
public static void main(String[] args) {
Program program = new Program();
List<TrialResult> trials = new ArrayList<TrialResult>();
int countTrials = 1;
for (int j = 0; j < countTrials; j++) {
long t0 = 0, t1 = 0;
t0 = System.nanoTime();
for (long i = 0; i < 2073600; i++) {
program.chainedIf();
}
t1 = System.nanoTime();
long chainIf = t1 - t0;
t0 = System.nanoTime();
for (long i = 0; i < 2073600; i++) {
program.multipleIf();
}
t1 = System.nanoTime();
long multipleIf = t1 - t0;
t0 = System.nanoTime();
for (long i = 0; i < 2073600; i++) {
program.guardIf();
}
t1 = System.nanoTime();
long guardIf = t1 - t0;
System.out.printf("Trial %d completed\r\n", j+1);
trials.add(new TrialResult(guardIf, multipleIf, chainIf));
}
long chainIf = 0, multipleIf = 0, guardIf = 0;
for (TrialResult r : trials) {
chainIf += r.ChainedIf;
multipleIf += r.MultipleIf;
guardIf += r.GuardIf;
}
System.out.printf("%d, %d, %d", guardIf / trials.size(), multipleIf / trials.size(), chainIf / trials.size());
}
private Program() {
x = 9;
y = 2;
z = 8;
}
private void chainedIf() {
if (x > 0) {
if (y > 0) {
if (z > 0) {
if (complexCondition()) {
noOp();
}
}
}
}
}
private void multipleIf() {
if (x > 0 && y > 0 && z > 0 && complexCondition()) {
noOp();
}
}
public void guardIf() {
if (x <= -1) {
return;
}
if (y <= -1) {
return;
}
if (z <= -1) {
return;
}
if (!complexCondition()) {
return;
}
noOp();
}
private boolean complexCondition() {
return (x > 0 &&
y < x &&
y + z > x
);
}
private void noOp() {
return;
}
}
答案 0 :(得分:0)
为什么所有方法的运行需要更长时间(在chainIf的情况下,几乎多300%的时间),当它们检查的值允许它们全部缩短curcuit时?
因为您的基准测试有问题。请阅读类似问题的答案:
Java loop gets slower after some runs / JIT's fault?