在块中连续使用相同的方法会重新计算方法吗?
Successive use of same method in block recalculates the method?
我一直假设每次调用 Java 中的方法时,该方法都会再次执行。我假设 return 值不会自动存储,除非我将其存储在变量中。
然后我 运行 在 Princeton's algs4.BST class 中的这段代码中,他们分别调用了三个方法两次:
private boolean check() {
if (!isBST()) StdOut.println("Not in symmetric order");
if (!isSizeConsistent()) StdOut.println("Subtree counts not consistent");
if (!isRankConsistent()) StdOut.println("Ranks not consistent");
return isBST() && isSizeConsistent() && isRankConsistent();
}
他们根本不关心性能吗?或者编译器是否足够聪明,保留每个方法的第一个 return 值以在 return 语句中使用?
抱歉,如果这是重复的,这个答案似乎应该存在,但我无法在此处或 Java 文档中找到它。我找到了这些(和其他)但它们没有回答我的问题:
Is this the cleanest way to repeat method call in Java?
Java 语言规范明确且无条件地声明方法调用表达式的计算涉及执行指定方法的代码。 JLS 8 是这样说的:
At run time, method invocation requires five steps. First, a target
reference may be computed. Second, the argument expressions are
evaluated. Third, the accessibility of the method to be invoked is
checked. Fourth, the actual code for the method to be executed is
located. Fifth, a new activation frame is created, synchronization is
performed if necessary, and control is transferred to the method code.
(JLS 8, 15.12.4;已强调)
因此,无论是否可以预期计算相同的值,第二次调用方法都会产生第二次成本。可以想象 JIT 编译可以对此进行优化,但是除了是否要计算相同的结果之外还有更多的考虑因素,而且您无论如何都不太可能看到仅由给定方法的两次调用触发的任何 JIT 操作。
底线:是的,代码的作者根本不关心性能。他们可能认为所提供的实现比避免冗余方法调用的实现更清晰,或者他们可能出于其他个人原因做出选择。这种对实用性的漠视在服务于学术目的的代码中并不少见,例如所呈现的代码。
该代码中的 check
函数仅在上下文中调用:
assert check();
生产代码中通常不会启用断言,如果未启用断言,assert
语句 绝对不会执行任何操作。所以check
函数在调试运行时只会是运行。这个事实并没有允许任意低效,但不尝试优化此类代码是很常见的。代码 运行 作为断言的要点是明显且无可争辩地正确,同时它验证不变量、前提条件或后置条件,以及优化——即使是像将结果保存在局部变量中这样的微不足道的优化——也无助于那个目标。
An assertion is an assert statement containing a boolean expression. An assertion is either enabled or disabled. If an assertion is enabled, execution of the assertion causes evaluation of the boolean expression and an error is reported if the expression evaluates to false. If the assertion is disabled, execution of the assertion has no effect whatsoever.
我一直假设每次调用 Java 中的方法时,该方法都会再次执行。我假设 return 值不会自动存储,除非我将其存储在变量中。
然后我 运行 在 Princeton's algs4.BST class 中的这段代码中,他们分别调用了三个方法两次:
private boolean check() {
if (!isBST()) StdOut.println("Not in symmetric order");
if (!isSizeConsistent()) StdOut.println("Subtree counts not consistent");
if (!isRankConsistent()) StdOut.println("Ranks not consistent");
return isBST() && isSizeConsistent() && isRankConsistent();
}
他们根本不关心性能吗?或者编译器是否足够聪明,保留每个方法的第一个 return 值以在 return 语句中使用?
抱歉,如果这是重复的,这个答案似乎应该存在,但我无法在此处或 Java 文档中找到它。我找到了这些(和其他)但它们没有回答我的问题:
Is this the cleanest way to repeat method call in Java?
Java 语言规范明确且无条件地声明方法调用表达式的计算涉及执行指定方法的代码。 JLS 8 是这样说的:
At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. Third, the accessibility of the method to be invoked is checked. Fourth, the actual code for the method to be executed is located. Fifth, a new activation frame is created, synchronization is performed if necessary, and control is transferred to the method code.
(JLS 8, 15.12.4;已强调)
因此,无论是否可以预期计算相同的值,第二次调用方法都会产生第二次成本。可以想象 JIT 编译可以对此进行优化,但是除了是否要计算相同的结果之外还有更多的考虑因素,而且您无论如何都不太可能看到仅由给定方法的两次调用触发的任何 JIT 操作。
底线:是的,代码的作者根本不关心性能。他们可能认为所提供的实现比避免冗余方法调用的实现更清晰,或者他们可能出于其他个人原因做出选择。这种对实用性的漠视在服务于学术目的的代码中并不少见,例如所呈现的代码。
该代码中的 check
函数仅在上下文中调用:
assert check();
生产代码中通常不会启用断言,如果未启用断言,assert
语句 绝对不会执行任何操作。所以check
函数在调试运行时只会是运行。这个事实并没有允许任意低效,但不尝试优化此类代码是很常见的。代码 运行 作为断言的要点是明显且无可争辩地正确,同时它验证不变量、前提条件或后置条件,以及优化——即使是像将结果保存在局部变量中这样的微不足道的优化——也无助于那个目标。
An assertion is an assert statement containing a boolean expression. An assertion is either enabled or disabled. If an assertion is enabled, execution of the assertion causes evaluation of the boolean expression and an error is reported if the expression evaluates to false. If the assertion is disabled, execution of the assertion has no effect whatsoever.