假设我有一个方法用于验证特定值,例如方法isEven
:
public static boolean isEven(int evenSize) {
return evenSize % 2 == 0;
}
我使用此方法验证外部输入(例如来自磁盘或来自用户)。但之后我也在一个需要偶数值的方法中使用这个方法:
public static String padToEven(int evenSize, String string) {
if (!isEven(evenSize)) { // <-- duplication of isEven method
throw new IllegalArgumentException("evenSize argument is not even");
}
if (string.length() >= evenSize) {
return string;
}
StringBuilder sb = new StringBuilder(evenSize);
sb.append(string);
for (int i = string.length(); i < evenSize; i++) {
sb.append('x');
}
return sb.toString();
}
所以基本上我们向padToEven()
提供已经验证的参数,并使用相同的isEven
函数验证参数。 JIT编译器(比如Java的第8版)是否可以找到第二个调用并将其优化掉?
您可以假设检查不依赖于动态值(即,它对所提供的参数值是确定的)。除了返回值之外,它也没有任何副作用,例如记录语句。
答案 0 :(得分:2)
我不认为Java会进行任何过程间分析。但是,该方法有可能被内联。当你内联所有内容时,那就是
if (evenSize % 2 != 0) {
throw new IllegalArgumentException("evenSize argument is not even");
}
... some code not changing evenSize
if (evenSize % 2 != 0) {
throw new IllegalArgumentException("evenSize argument is not even");
}
这是非常简单的优化。这种内联不是你可以依赖的东西,因为有一个内联限制可以很快达到。
OTOH,测试非常简单,可能会优化到
public static boolean isEven(int evenSize) {
return (evenSize & 1) == 0;
}
使用更快的操作。但这并不是我所关心的事情(因为有许多其他代码,所以你不能获得太多)。
我想,最好的优化是消除StringBuilder
。什么???是的,严肃地说,char[]
会这样做:
char[] result = new char[evenSize];
for (int i = 0; i < string.length(); i++) {
result[i] = string.charAt(i);
}
for (int i = string.length(); i < evenSize; i++) {
result[i] = 'x';
}
return new String(result);
前段时间,我做了一些测量表明它应该更快。最近的JIT可能已经改变了。不是重要的部分:
完全没有。除非你
不要这样做。幸运的是,JIT采用简短的方法针对干净的代码进行了优化。它无法改善您的算法和数据结构,因此您可以在需要时进行优化。微观优化的回报要小得多。
您的上述代码很好,请勿触摸它。