在循环内创建对象与在循环之前创建一个临时对象

时间:2013-11-07 20:30:40

标签: java android performance

以下是我正在质疑的一段代码

        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左右,会怎么样?

6 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

看看标题,我知道这将是另一个被误导的表现问题。

有几件事:

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

至于你在另一个答案中提出的GC评论:GC在后台发生,是智能的,并做出你绝对无法控制的决定(除了JVM命令行调整 - 不要兴奋,基于关于你问这个问题的事实,你可能没有能力做出关于调整参数的好决定。将引用从一个位置移动到另一个位置使您无法控制GC如何处理它。每次循环都不再可以访问先前的引用,GC将在未来的未定义点清理它。

答案 2 :(得分:3)

对于所有现实的,可衡量的案例,两种表现之间绝对没有区别。事实上,我很确定(诚然我不确定)他们会产生完全相同数量的作业和参考创作。 JVM创建N个引用持有者是愚蠢的。它只是重用第一次迭代中创建的那个,只是在下一个赋值中给它引用。这意味着两种情况下只使用一个参考持有者(假设这是真的)。​​

答案 3 :(得分:2)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

唯一改变的是,在第二个循环中,您创建了this.options.size() - 次参考butt