java - JIT编译器优化: second method call with same parameter

标签 java validation optimization parameters jit

假设我有一个用于验证特定值的方法,例如方法 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 中)是否有可能找到第二个调用并将其优化掉?

您可以假设检查不依赖于动态值(即它对提供的参数值是确定性的)。除了返回值(例如日志语句)之外,它也没有任何副作用。

最佳答案

我认为 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 针对具有短方法的干净代码进行了优化。它无法改进您的算法和数据结构,因此您可以在真正需要时进行优化。微观优化的返回要低得多。

你上面的代码很好,不要碰它。

关于java - JIT编译器优化: second method call with same parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41653877/

相关文章:

java - 直接转换File对象中的BufferedImage

用于 url 验证的 PHP 正则表达式,filter_var 过于宽松

用于错误验证的 CSS 表单高亮显示

php - 将大量图像分组

sql - mysql 三联结

java - 使用自定义 AST 节点类型进行树过滤时,如何避免抛出 ClassCastException?

java - 通过套接字发送的字符串与应有的内容不匹配

java - 检查 20 个随机 boolean 值是否具有相同的值

javascript - jQuery Validate将错误视为单独的实例,而不是将它们组合在一起

mysql - 过滤按列分组的大型数据库记录