Java方法调用vs使用variables

最近我和我的团队负责人讨论了使用临时variables和调用getter方法的问题。 我有很长一段时间的意见,如果我知道我将不得不调用一个简单的getter方法很多次,我会把它放到一个临时variables,然后使用该variables。 我认为这在风格和performance上都会更好。 但是,我的领导指出,在Java 4及更新版本中,这是不正确的。 他是一个使用较小variables空间的信徒,所以他告诉我调用getter方法的性能受到的影响非常小,而不是使用tempvariables,因此使用getters更好。 但是,我并不完全相信他的论点。 你们有什么感想?

永远不要编码的性能,始终代码的可读性。 让编译器做这个工作。

他们可以改进编译器以更快地运行良好的代码,突然你的“快速”代码实际上减慢了系统的速度。

你的领导是正确的。 在VM的现代版本中,返回私有字段的简单getter被内联,这意味着方法调用的性能开销不存在。

不要忘记,通过将getSomething()的值分配给一个variables而不是调用它两次,假设getSomething()在第二次调用它时会返回相同的结果。 也许在你谈论的情况下,这是一个有效的假设,但是有些情况并非如此。

这取决于。 如果你想清楚地说明你一次又一次使用相同的值,我将它分配给一个临时variables。 我会这样做,如果getter的调用有点冗长,像myCustomObject.getASpecificValue()

如果代码可读,您将获得更less的错误。 所以这是主要的一点。

性能差异很小或根本不存在。

如果考虑到代码的进化,v1.0中的简单getter往往会成为v2.0中不那么简单的getter。

把一个简单的getter改为not-so-simple getter的编码者通常不知道有一个函数调用了这个getter 10次而不是1,并且从来没有纠正过。

这就是为什么从DRY主体的angular度来看,caching重复使用的值是有意义的。

我不会牺牲“代码可读性”几微秒。
也许这是真的,getter性能更好,可以在运行时节省几个微秒。 但是我相信,当bug修复时间到来时,variables可以为您节省几个小时甚至几天的时间。

对不起,非技术性的答案。

我认为,如果满足一些条件,JVM的最新版本通常足够聪明地自动caching函数调用的结果。 我觉得这个函数一定没有副作用,每次调用的时候都可以得到相同的结果。 请注意,对于简单的getter,这可能也可能不是这样,这取决于你的类中的其他代码对字段值做了什么。

如果情况并非如此,被调用的函数会进行重要的处理,那么您确实会更好地将其结果caching在临时variables中。 虽然通话的开销可能是微不足道的,但是如果你经常打电话的话,一个繁忙的方法会吃你的午餐。

我也练习你的风格; 即使不是出于性能的原因,当我的代码没有充满函数调用的级联时,我发现我的代码更清晰。

如果它只是getFoo()那就不值得。 通过将它caching到一个临时variables中,你不会快得多,也许getFoo()麻烦,因为getFoo()可能会返回不同的值。 但是,如果它是像getFoo().getBar().getBaz().getSomething()类似的东西,并且您知道该值不会在代码块中更改,那么可能有一个理由使用临时variables以提高可读性。

一般性评论:在任何现代系统中,除I / O之外,不要担心性能问题。 快速的CPU和大量的内存意味着,所有其他问题在大多数情况下完全不影响系统的实际性能。 [当然,caching解决scheme也有例外,但它们非常罕见。]

现在来解决这个问题,是的,编译器会内联所有的获取。 然而,即使这不是真正的考虑,真正重要的是你的代码的所有可读性和stream程。 如果使用多次调用(如customer.gerOrder()。getAddress()更好地捕获本地variables,则用本地variablesreplace间接更好。

虚拟机可以比之后声明的任何局部variables更有效地处理前四个局部variables(请参阅lload和lload_ <n>指令 )。 所以caching(内联)getter的结果可能会影响你的性能。

当然,对他们来说性能的影响几乎可以忽略不计,所以如果你想优化你的代码,确保你真的解决了一个实际的瓶颈!

不使用临时variables来包含方法调用结果的另一个原因是使用该方法获得最新的值。 这对于实际的代码来说不是问题,但是当代码改变时,这可能会成为一个问题。

如果你确定getter会在整个范围内返回相同的值,我赞成使用tempvariables。 因为如果你有一个名字长度大于或等于10的variables,getter在可读性方面看起来很糟糕。

我用一个非常简单的代码对它进行了testing:

  • 用int的一个简单的getter创build了一个类(我尝试了Num的final和non-final值,没有看到任何区别,但是在这种情况下num不会改变…!):

     Num num = new Num(100_000_000); 
  • 比较2个不同的循环:

     1: for(int i = 0; i < num.getNumber(); ++i){(...)} 2: number = num.getNumber(); for(int i = 0; i < number; ++i){(...)} 

结果第一个是3毫米左右,第二个是2毫米左右。 所以有一个很小的差别,没有什么可担心的小循环,在大的迭代中可能会更成问题,或者如果你总是调用getter并且需要它们。 例如,在image processing,如果你想快速,不要反复使用吸气剂,我会build议…