1

这是我正在质疑的一段代码

        for (int i = 0; i < this.options.size(); i++) {
            RadioButton butt = this.options.get(i);
            //do something with butt
        }

如果我将其更改为:

        RadioButton butt;
        for (int i = 0; i < this.options.size(); i++) {
            butt = this.options.get(i);
            //do something with butt
        }

编辑:如果此代码每秒执行 30-50 次,options大小约为 20,怎么样?

4

6 回答 6

4

对于所有现实的、可衡量的情况,两者在性能方面绝对没有区别。事实上,我很确定(诚然我不确定)它们会产生完全相同数量的分配和参考创建。JVM 创建 N 个引用持有者是愚蠢的。它会简单地重用在第一次迭代中创建的那个,只需在下一次赋值中给它引用。这意味着两种情况都只使用一个参考持有人(假设这是真的)。

于 2013-11-07T20:42:33.210 回答
3

你不是在这里创建对象,你只是在创建引用,你是创建一个还是多个引用并不重要。

于 2013-11-07T20:32:56.000 回答
3

看着标题,我知道这将是另一个被误导的性能问题。

有几件事:

  • 不,除了变量的范围之外,它们实际上是相同的。
  • 一般来说,如果你担心这样的微优化,那么你就是把时间花在了完全错误的事情上。在这种情况下,它没有实际意义,因为没有区别,但即使您在谈论例如一项作业:
    1. 与您正在做的其他事情相比,差异是纳秒级并且完全可以忽略不计。
    2. 编译器在优化方面比你聪明得多。
    3. JVM 解释器和热点编译器也比你聪明得多。
  • 如果您没有设置明确的性能要求,并且您还没有确定您的代码不满足这些要求,并且您还没有分析您的代码并确定瓶颈在哪里,那么您就没有业务提出这样的优化问题。

至于您在另一个答案中所做的 GC 评论: GC 发生在后台,是智能的,并且做出您完全零控制的决定(除了 JVM 命令行调整 - 不要兴奋,基于事实你问了这个问题,你可能没有能力对调整参数做出正确的决定)。将引用从一个地方移动到另一个地方不会让您对 GC 处理它的方式进行重大控制。每次循环之前的引用不再可达,GC 将在未来的未定义点清理它。

于 2013-11-07T20:38:43.417 回答
2

我认为代码和性能几乎相同,只是看起来不同。您不是在创建新实例,而只是从您的集合中复制对象的引用。

但我喜欢并且通常使用第二种方法。

于 2013-11-07T20:34:30.193 回答
0

差异并不大,因为对象的分配是这里最大的成本。此外,编译器将使您的代码更有效率,因此最终它的性能成本是相同的。

于 2013-11-07T20:32:34.620 回答
0

RadioButton在这两种情况下,您都在循环中创建对象,因为RadioButton butt它只是一个引用而不是对象的实例。大概是this.option.get(i)哪个创建了您的对象。所以我的回答是:不。

唯一改变的是,在第二个循环中,您正在创建this.options.size()-times 引用butt

于 2013-11-07T20:35:47.623 回答