Java 空检查性能
Java null check performance
我想知道在 java 中通过直接比较或使用 Objects.isNull() 方法检查对象是否为 null 是否有任何显着差异。
public class Test {
public final static Long ITERATIONS = 100000000L;
@Test
public void noFnCalls() {
balong startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = x == null;
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("noFnCalls ellapsed time: " + estimatedTime);
}
@Test
public void withFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = Objects.isNull(x);
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("withFnCalls ellapsed time: " + estimatedTime);
}
}
令人惊讶的是,至少对我而言,完成“noFnCalls”总是需要更多时间。我期待的结果恰恰相反,因为它会导致使用堆栈进行方法调用。
这是输出:(显然,每次都会更改,但“noFnCalls”总是更高)
noFnCalls ellapsed time: 583
withFnCalls ellapsed time: 463
为什么会产生这个?
您看到的结果可能是由于 运行 "noFnCalls" 首先,没有在测试和测量之前引入适当的预热。
我明白了:
withFnCalls ellapsed time: 444
noFnCalls ellapsed time: 471
withFnCalls ellapsed time: 334
noFnCalls ellapsed time: 331
withFnCalls ellapsed time: 330
noFnCalls ellapsed time: 325
withFnCalls ellapsed time: 331
noFnCalls ellapsed time: 326
withFnCalls ellapsed time: 326
noFnCalls ellapsed time: 328
正在使用
import java.util.Objects;
public class Test {
public final static Long ITERATIONS = 100000000L;
public static void main(String args[]) {
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
}
public static void noFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = x == null;
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("noFnCalls ellapsed time: " + estimatedTime);
}
public static void withFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = Objects.isNull(x);
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("withFnCalls ellapsed time: " + estimatedTime);
}
}
和
withFnCalls ellapsed time: 3618
noFnCalls ellapsed time: 3361
withFnCalls ellapsed time: 3445
noFnCalls ellapsed time: 3278
withFnCalls ellapsed time: 3350
noFnCalls ellapsed time: 3292
withFnCalls ellapsed time: 3309
noFnCalls ellapsed time: 3262
withFnCalls ellapsed time: 3293
noFnCalls ellapsed time: 3261
如果我增加到 1000000000L 次迭代。这是通过 Java 9 64 位服务器 jvm,构建 9+181,由 Oracle,运行 在 Windows 10 上使用一台装有 Intel i5-2600 cpu 的机器完成的。
正如其他人所说,微基准测试 很难 很多不同的因素都会影响结果。您不应该通过此类测试得出结论。这种测试并不能说明什么 - 任何差异都容易在彼此如此接近的噪声测量代码中丢失。
java 中有关微基准测试的强制性推荐线程:How do I write a correct micro-benchmark in Java?。
我想知道在 java 中通过直接比较或使用 Objects.isNull() 方法检查对象是否为 null 是否有任何显着差异。
public class Test {
public final static Long ITERATIONS = 100000000L;
@Test
public void noFnCalls() {
balong startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = x == null;
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("noFnCalls ellapsed time: " + estimatedTime);
}
@Test
public void withFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = Objects.isNull(x);
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("withFnCalls ellapsed time: " + estimatedTime);
}
}
令人惊讶的是,至少对我而言,完成“noFnCalls”总是需要更多时间。我期待的结果恰恰相反,因为它会导致使用堆栈进行方法调用。
这是输出:(显然,每次都会更改,但“noFnCalls”总是更高)
noFnCalls ellapsed time: 583
withFnCalls ellapsed time: 463
为什么会产生这个?
您看到的结果可能是由于 运行 "noFnCalls" 首先,没有在测试和测量之前引入适当的预热。
我明白了:
withFnCalls ellapsed time: 444
noFnCalls ellapsed time: 471
withFnCalls ellapsed time: 334
noFnCalls ellapsed time: 331
withFnCalls ellapsed time: 330
noFnCalls ellapsed time: 325
withFnCalls ellapsed time: 331
noFnCalls ellapsed time: 326
withFnCalls ellapsed time: 326
noFnCalls ellapsed time: 328
正在使用
import java.util.Objects;
public class Test {
public final static Long ITERATIONS = 100000000L;
public static void main(String args[]) {
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
withFnCalls();
noFnCalls();
}
public static void noFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = x == null;
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("noFnCalls ellapsed time: " + estimatedTime);
}
public static void withFnCalls() {
long startTime = System.currentTimeMillis();
Object x = new Object();
Long i;
for (i = 0L; i < ITERATIONS; i++) {
boolean t = Objects.isNull(x);
}
long estimatedTime = System.currentTimeMillis() - startTime;
System.out.println("withFnCalls ellapsed time: " + estimatedTime);
}
}
和
withFnCalls ellapsed time: 3618
noFnCalls ellapsed time: 3361
withFnCalls ellapsed time: 3445
noFnCalls ellapsed time: 3278
withFnCalls ellapsed time: 3350
noFnCalls ellapsed time: 3292
withFnCalls ellapsed time: 3309
noFnCalls ellapsed time: 3262
withFnCalls ellapsed time: 3293
noFnCalls ellapsed time: 3261
如果我增加到 1000000000L 次迭代。这是通过 Java 9 64 位服务器 jvm,构建 9+181,由 Oracle,运行 在 Windows 10 上使用一台装有 Intel i5-2600 cpu 的机器完成的。
正如其他人所说,微基准测试 很难 很多不同的因素都会影响结果。您不应该通过此类测试得出结论。这种测试并不能说明什么 - 任何差异都容易在彼此如此接近的噪声测量代码中丢失。
java 中有关微基准测试的强制性推荐线程:How do I write a correct micro-benchmark in Java?。