我开发了一个小型库,可以使用注释进行声明性参数验证,如下所示:
@Validate({"not null | number"})
public static Integer notNullAnnotated(Integer number) {
return number++;
}
现在我正在对纯Java代码版本进行基准测试:
public static Integer notNullInline(Integer number) {
if (number != null) {
return number++;
} else {
throw new IllegalArgumentException("argument should not be null");
}
}
这是测试:
@Test
public void performanceTest() {
long time = System.nanoTime();
for (int i = 0; i < iterationCount; i++) {
notNullAnnotated(i);
}
System.out.println("time annotated : " + (System.nanoTime() - time));
time = System.nanoTime();
for (int i = 0; i < iterationCount; i++) {
notNullInline(i); // TODO does compiler do any optimization here?
}
System.out.println("time inline : " + (System.nanoTime() - time));
}
我知道这不是进行基准测试的预期方式。现在我宁愿避免为这个简单的测试添加任何实用程序库(因为即使这样结果也很好),但是我想知道编译器是否在这里进行了任何优化?
答案 0 :(得分:2)
由于您已经远远落后于过早的优化路径,请查看Hotspot的PrintAssembly
和CompileThreshold
标志。第一个选项允许您检查Hotspot生成的程序集。第二个允许您设置JIT启动时的阈值。
答案 1 :(得分:1)
当然,及时编译器将优化您的代码(假设迭代计数相当高),就像在运行该代码的实际程序中一样。因此,在基准测试中,优化本身是可取的。当然,如果代码的人为性质允许实际代码不可用的优化,那么您将遇到问题。在您的情况下,编译器可能会断定notNullInline永远不会抛出,因此没有效果,并选择删除整个循环。
已经讨论过编写正确的基准