【发布时间】:2010-03-06 03:19:14
【问题描述】:
Java 编译器是否足够聪明,可以通过提取以下循环来优化以下循环
Double average = new Double( totalTime / callCount );
退出for循环?
public double computeSD( Set values, int callCount, long totalTime ) {
double diffs = 0.0d;
for( Iterator i=values.iterator(); i.hasNext(); ) {
double value = ( ( Double )i.next() ).doubleValue();
Double average = new Double( totalTime / callCount );
diffs += ( value – average.doubleValue() ) * ( value – average.doubleValue() );
}
double variance = diffs / callCount;
return Math.sqrt( variance );
}
【问题讨论】:
-
JIT 编译器端的流分析很容易告诉您
Double对象不会在任何地方转义,因此只使用它们包含的值。我敢说上面的功能应该很容易按照 OP 寻求的方式进行优化。 -
我对此表示怀疑。使用原始双精度,并使 callCount 和 totalTime 最终可能会有所帮助,但我仍然对此表示怀疑。
-
@Thilo:对局部变量使用
final对字节码没有影响。当然,变量的恒常与否是由 JIT 编译器决定的。 -
为了帮助编译器,让尽可能多的变量为final。据我所知,您可以将 i、value、average、values、callCount、totalTime 和 variance 设为 final。
-
@Chris Dennett:是的,也不是。制作局部变量
final主要是对程序员的帮助,以阻止(禁止)他们重新分配变量(这确实有助于编译器)。但是,如果您实际上只是将每个局部变量分配一次作为一种习惯,那么final的存在或不存在根本不会改变字节码输出。 (字段的情况有所不同。我确实有一个政策是尽可能多地创建字段final。)
标签: java performance compiler-optimization