Java控制结构中的自动编译器优化?

pmc*_*mcs 1 java compiler-construction for-loop

我有一个关于Sun JDK中提供的Java编译器"智能"的快速问题.具体来说,是否足够聪明地提前评估出现在for()循环的条件部分中的任何函数,而不是在循环的每次迭代中评估它们?

例如,请考虑以下代码.

// Array of doubles to "hold" the array.
private double matrix[][];

public int getCols() {
    // Compute the number of columns in a matrix.
}

public int getRows() { 
    // Compute the number of rows in a matrix.
}

// Compute the sum of all elements in the matrix.
public double sum() {

    double result = 0;

    for (int r = 0; r < getRows(); r++) {
        for (int c = 0; c < getCols(); c++) {
            result += this.matrix[r][c];
        }
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

显然,我可以修改sum()方法,以确保在循环的每次迭代中都不会通过将其更改为getRows()和getCols()来计算

public double sum() {

    double result = 0;
    int numRows = getRows();
    int numCols = getCols();

    for (int r = 0; r < numRows; r++) {
        for (int c = 0; c < numCols; c++) {
            result += this.matrix[r][c];
        }
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道编译器是否足够智能以预先评估这些本身.也就是说,它是否会自动发现计算出提前出现在条件数中的函数而不是在每次迭代时评估它们的计算成本更低?

谢谢!

小智 5

通常,这样的优化是错误的.这些方法是虚拟的,因此可以在子类中进行更改以完成不同的操作(例如返回随机数),并且可能很难不能静态地证明(是的,它需要证明)它们返回相同的每次迭代的价值,即使它们是final.事实上,也许他们根本不这样做(想想另一个线程并行改变行数/列数 - 是的,在这种情况下你会遇到很多其他问题,但仍需要考虑).

除此之外,编译器不需要优化任何东西:在运行时,JIT编译器可以进行更多优化.例如,它可以生成具有虚拟调用内联的代码,并且它可以(取决于代码)能够分解错误(至少如果它们无条件地返回常量).但是,如果不能改变语义,那么它也不会这样做.如果真的很重要,那就自己动手吧.无论哪种方式,检查它是否是一个瓶颈.