今天我正在阅读一些代码并看到了这个:
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));
...
然后我停下来想知道:代码的第二部分是否真的更高效还是不重要?编译器是否会以任何方式生成相同的字节代码?
答案 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。