调用函数哪个更好:两次或将结果存储在变量中?

时间:2013-04-20 04:49:05

标签: java performance variables

我多次怀疑,但没有弄明白正确的解决方案。这次我要清除它。我有像

这样的情况
1. 
String sNumber="ksadfl.jksadlf";
if(sNumber.lastIndexOf('.')>0)
   //do something
...
...
if(sNumber.lastIndexOf('.')>1)
 //do something
...

2.
int index = sNumber.lastIndexOf('.');
if(index>0)
//do something
...
...
if(index>1)
//do something
...

第一种方式和第二种方式之间的权衡是什么?哪一个更好地将结果存储在一个变量中或者两次调用该函数?

4 个答案:

答案 0 :(得分:5)

在这个例子中,从性能的角度来看,第二种形式更好(在大多数合理的情况下 1 ),并且(IMO)更具可读性。

一般来说,需要考虑几个权衡因素:

  • 可读性比效率更重要吗?
  • 调用方法两次而不是一次“性能影响”多少?

此外,您还需要考虑方法可能有副作用的情况,以及它是否可以在两个连续的调用中给出不同的答案。在这些情况下,调用方法两次在语义上与调用一次并将结果存储在临时变量中不同。


1 - index变量使堆栈帧1个字大。通常情况下这没关系,但是如果代码是以递归方式调用的递归方法,那么1个额外的单词乘以一些嵌套调用可能会产生StackOverflowError

答案 1 :(得分:3)

由于这个问题仅涉及2个精益lastIndexOf电话,因此两者之间几乎没有差别。如果它是通过代理进行远程调用或者进行数据库命中的事情,那么将方法结果存储到变量中会看到一些改进。

enter image description here

再次调用该方法的好处是,您将始终获取索引的最新值,以防它在早期块中的某处被操纵。在大多数情况下,#2将是正确的选择,但对于上面的确切示例,它是#1。

答案 2 :(得分:2)

你的怀疑是显而易见的。你的第二种方法是好的和有效的。

因为如果你的字符串变量数据每次都没有变化,那么每次都不需要获取索引。不,需要一次又一次地使用sNumber.lastIndexOf('.')。每次运行lastIndexOf()函数时,都需要额外的时间和其他资源。

因此,最好使用第二个选项,使您的程序更快更短。

答案 3 :(得分:1)

您的问题是内存使用率和CPU使用率之间的经典折衷。

首先,您必须确定是否希望程序在内存中占用的空间很小,或者是否希望它快速运行。解决方案1很可能导致内存使用最少(因为您没有存储int),而解决方案2将导致最快的执行时间,因为您不必执行两次indexOf计算。

那就是说在内存中存储计算并不总能导致最快的程序。内存占用量小通常会导致缓存未命中次数减少。缓存未命中通常比简单地进行两次计算要慢得多。

要了解最小化缓存未命中的重要性,请查看有关C ++中列表与向量性能的this帖子。人们会期望列表比矢量快得多,因为不必复制数据。然而,列表实现确实具有更多的随机数据访问,因此更多的缓存未命中导致向量更快。

最后,我建议您测量两种解决方案的性能,并确定您最喜欢的内存和CPU使用情况的组合。