是否在编译器优化的同一语句中多次调用同一方法?

Mag*_*s W 3 java optimization android compiler-optimization java-8

假设我在Java 8中做了类似的事情(特别是Android)

String name = someObject.getName() != null ? someObject.getName() : "null";
Run Code Online (Sandbox Code Playgroud)

并且该方法getName()可能会有很多调用其他方法来解析名称.还假设我经常调用这段代码.

做这样的事情会更好,性能更好吗?

String name = someObject.getName();
name = name != null ? name : "null";
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 5

这看起来像一个可能的优化,称为CSE ; 一个JVM据我所知这是否(但不知道关于Android).

但这很大程度上取决于它是什么getName,如果它在内部分配其他对象并做其他事情.不幸的是,我甚至无法告诉如何证明我错了或在这里(可能需要调查); 老实说,我有自己这样做的习惯.例如:

for(int i=0;i<list.size();++i){

}
Run Code Online (Sandbox Code Playgroud)

我试着总是int size = list.size()在循环之前提取; 即使这在我的理解中受到scalar replacement优化.

  • 您应该始终避免代码重复,这已经是为了清晰起见.使用像`someObject.getName()!= null这样的表达式?someObject.getName():"null"`,读者并不明白`someObject.getName()`每次真正评估相同的结果(尽管很明显,作者*假定*那个),这不是只依赖于`getName()`方法的实现,还取决于`someObject`变量的性质,它可能是一个可变的共享变量.但请考虑[这些替代方案](/sf/ask/3674692451/#comment91935865_52495606)...... (7认同)
  • 在内联所有个人调用后,CSE将适用.然后,优化器能够查看代码是否是无副作用的,并且每次都归结为相同的操作.关于循环中的`list.size()`,它可以像对同一方法的重复调用一样进行优化,但是,如果循环体包含停止优化器的操作,例如影响线程间可见性的操作,它' d需要一个可证明的纯本地列表实例仍然具有该优化.否则,它可能最终在每次重新读取`size`字段的代码中. (2认同)