Java 将值存储为变量还是再次调用方法更好?

Java 将值存储为变量还是再次调用方法更好?,java,memory-management,jvm,jit,Java,Memory Management,Jvm,Jit,最近,我开始学习一些Java。从我对JVM的了解来看,JIT在需要CPU周期的操作(即调用一个方法)上看起来非常快,但同时也使它需要内存。所以,当我需要与以前相同的方法的相同输出时,通常更好的方法是将以前的输出存储在变量中并再次使用它(同时一直将其保存在内存中),还是再次调用相同的方法?创建临时变量的速度不太可能较慢 但更重要的是:将返回值存储在变量中可以提高代码的可读性和可维护性。例如: Biz nibb = getBiz(); frobnicate(nibb.foo(), nibb.bar(

最近,我开始学习一些Java。从我对JVM的了解来看,JIT在需要CPU周期的操作(即调用一个方法)上看起来非常快,但同时也使它需要内存。所以,当我需要与以前相同的方法的相同输出时,通常更好的方法是将以前的输出存储在变量中并再次使用它(同时一直将其保存在内存中),还是再次调用相同的方法?

创建临时变量的速度不太可能较慢

但更重要的是:将返回值存储在变量中可以提高代码的可读性和可维护性。例如:

Biz nibb = getBiz();
frobnicate(nibb.foo(), nibb.bar());
galuncify(nibb.bar());
如果我决定使用
nibb.biz()
的值代替
nibb.bar()
,我必须记住在两个地方替换它。如果改用变量,则不会出现此问题:

Biz nibb = getBiz();
Bar bar = nibb.bar();
frobnicate(nibb.foo(), bar);
galuncify(bar);

还要注意方法调用是如何变得更具可读性的。

有很多因素,包括个人喜好、方法的花费、方法所做的修改等

  • 对于基本的JavaBean/map/list-get方法,我通常会调用两次以获得可编辑性,但这是个人喜好。方法也是一样
  • 对于返回值的更昂贵的操作(例如URL内容),最好存储,因为访问internet、获取数据和报告是一个漫长的操作
  • 如果该方法在获取数据时修改了任何内容,我将存储该值

最好将输出保存在变量中,而不是再次调用函数。变量将被保存在内存中,只要它需要。之后,自动垃圾收集将处理这些问题,以将其从内存中释放出来。但是,如果调用该函数,每次调用它时,它都会消耗其激活记录堆栈的内存。因此,如果您不希望程序内存不足,最好将结果存储在一个变量中,并在需要时使用它。

我理解这个问题,它会问哪个更好

Bar bar = foo.getBar();
bar.donkey();
...
bar.kong();

除非
getBar
价格昂贵,否则不太可能存在显著的性能差异。同样,内存也不太可能成为问题。专注于可理解性

有不同的意见

我相信马丁·福勒更喜欢后者。代码是独立的,并且可能更容易重构

我的观点是,重构服务于可理解性的目的。前者告诉我,在两个调用中使用的对象确实有一个共同的源,作为奖励,它是[type]。它通常更明确,虽然更详细,但进行的工作更少

另一方面,您可能希望将其转换为以下内容:

foo.donkey();
...
foo.kong();

不幸的是,答案几乎肯定是“视情况而定”。在几乎所有时间/记忆权衡很重要的情况下,你都希望你的行动基于证据而不是直觉


也就是说,使用真实数据测量程序的时间和内存配置文件。即使是相对简单的代码片段,也很难计算出内联、JIT、缓存未命中等的相对影响。

如果函数每次调用都返回一个新创建的对象,这意味着垃圾收集器需要做更多的工作。此外,方法中的任何和所有变量每次都会创建一个新的副本。addNumbers(intx,inty){return x+y;}将在每次调用该方法时创建两个新变量(它不会重用旧变量,而是创建新变量)。如果你叫它两次,那就是4个变量。如果你调用它一次并存储答案,那就是3个变量。因此,存储它已经使用了更少的内存和CPU,因为计算只需要进行一次。这是你所描述的+1的一个奇特的学术名称——在没有证据表明两次调用“getter”的潜在低效性实际上很重要的情况下,可读性和正确性应该被视为更重要的。请记住,对于一个简单的getter,它通常可以由JIT编译器内联,在这种情况下,只需要2或3条本机指令“我喜欢尽可能地消除像这样的临时变量。temp通常是一个问题,因为它们会导致在不需要传递的情况下传递大量参数。你很容易忘记他们在那里的目的。它们在长方法方面尤其阴险。当然要付出性能上的代价。。。现在计算两次。但它很容易优化。。。我认为这个答案根本不能解决他的问题。想象一下一系列“if age>100,if age>75”语句。假设年龄是通过一个方法检索到的,则执行“if guy.getAge()>100,guy.getAge()>75'等等。比先做'age=guy.getAge()'更好还是更差的内存/cpuwise,使用它?问题是哪种方法“通常更好”“.在这种情况下,CPU周期通常不是一个值得关注的问题,在不了解机器和JRE的情况下,无法回答有关速度的问题,甚至只能通过测试来回答,而整个事情只是一个过早的微优化的例子。
foo.donkey();
...
foo.kong();