我想知道这两种方法有什么区别吗
private int getSum(int a, int b) {
int total = a + b;
return total;
}
private int getSum2(int a, int b) {
return a+b;
}
我了解到编译器或解释器会自动对此进行优化。是吗?
这种差异将存在于字节码中,当然,其影响取决于实现。
您的附加
int
变量不能使用具有分离作用域的另一个变量的空间,因此当按字面执行(解释)时,它会将堆栈帧所需的大小增加四个字节。然而,像广泛使用的HotSpot JVM这样的环境在线程启动时就预先分配了线程的整个堆栈空间,并且不支持调整大小,因此通过这种实现,局部变量对内存消耗完全没有影响。
您可能会想说,如果将局部变量添加到递归方法中,所需的额外内存可能会增加,从而通过几次调用(在解释模式下)减少最大递归深度,但正如 this 答案中所讨论的,大于此的最大递归深度已经存在不确定性。
该答案还演示了编译/优化对所需堆栈跟踪的影响,在示例中将所需的堆栈空间减少了六倍。当您的方法是热点时,优化器会查看它,并且其框中的工具之一是转换为SSA形式,它仅知道变量,这些变量用于对数据传输进行建模。换句话说,这些变体之间的差异已经在中间表示中消除了。从那里开始,在生成本机代码时,这些值可能会映射到 CPU 寄存器,因此结果根本不需要堆栈空间。
尽管每次操作与调用者所做的任何事情融合在一起时,这样一个小方法更有可能被内联到调用者中,从而导致我们无法仅通过查看该方法来预测代码。无论哪种情况,是否使用临时局部变量都无关紧要。