声明一个局部变量并设置它比一次又一次地使用getter更有效吗?

时间:2011-10-20 15:00:13

标签: java android

今天我正在阅读一些代码并看到了这个:

    x.add(getResources().getString(R.string.none));
    x.add(getResources().getString(R.string.today));
    x.add(getResources().getString(R.string.tomorrow));
    ...

所以我想,“那效率很低!”并开始将其更改为:

    Resources res = getResources();
    x.add(res.getString(R.string.none));
    x.add(res.getString(R.string.today));
    x.add(res.getString(R.string.tomorrow));
    ...

然后我停下来想知道:代码的第二部分是否真的更高效还是不重要?编译器是否会以任何方式生成相同的字节代码?

6 个答案:

答案 0 :(得分:5)

编译器将生成相同的字节代码,但如果getResources()是一个简单的方法,那么JIT编译器可以 有效运行相同的代码执行时间。

我个人更喜欢第二种形式,因为它更清洁,更易读,而不是出于性能原因。

答案 1 :(得分:4)

永远不要相信编译器的优化,我多次失望。 在这种情况下,java编译器无法知道getResources()方法是否有任何副作用(如锁定对象,递增计数器),因为在构建项目时,它是针对stub api编译的,而不是真正的代码。 JIT在手机内部运行,因此它通常不如桌面编译器那么聪明。

我认为首选方式是:

final Resources res = getResources();
x.add(res.getString(R.string.none));
x.add(res.getString(R.string.today));
x.add(res.getString(R.string.tomorrow));
...

final关键字通常可以帮助编译器进行优化。

答案 2 :(得分:2)

与调试此错误所花费的时间相比,两者之间的毫秒差异无关:

x.add(getNewResources().getString(R.string.none));
x.add(getResources().getString(R.string.today));
x.add(getResources().getString(R.string.tomorrow));

糟糕。更新代码的人对它并不十分熟悉,并且不理解所有getStrings都必须来自NewResource,而不仅仅是第一个。他做了改变,编译,交付,现在发生了奇怪的事情,没有人知道为什么。

在您的第二个代码片段中,您通过实际创建一个名为“res”的公共位置,向代码的读者传达有一个共同位置,从中提取所有字符串。

答案 3 :(得分:1)

我会选择第二个版本,因为它更容易阅读。您不应该关心潜在的微不足道的性能影响,选择可读性而非性能问题几乎总是更好的选择。

最有可能在这段琐碎的代码中没有任何效果,因为JIT最终将生成相同的代码(尽管我不确定Dalvik JVM是否与Java JVM一样好)。

答案 4 :(得分:1)

开发人员指南不建议您在使用直接字段访问时使用getter:Avoid Internal Getters/Setters

  

没有JIT,直接字段访问速度比调用一个简单的getter快约3倍。使用JIT(直接字段访问与访问本地一样便宜),直接字段访问比调用一个简单的getter快约7倍。

但是,除非你拨多个电话,否则它不会产生太大影响。所以我会选择最易读的变体,这是我在第二个方面的意见,因为它的杂乱性较小。

答案 5 :(得分:0)

是。 Java编译器比10年前更加智能。如果getResource()的实施是{ return xxx; },这肯定会得到优化。但编译器能够进行更好的优化。 E.g。