今天我收到了一份代码审查评论,将这个匿名类提取到一个字段中,以避免一遍又一遍地分配它:
Collections.transform(new Function<Foo, Bar>(){
Bar apply(Foo foo) {
// do some simple local transform of foo into a Bar.
}
});
我回答说“没关系,JVM优化了它”。虽然我知道这个“优化”不会以任何方式影响性能,但我认为使代码可以内联访问的附加价值是值得的,我很好奇我是否对JVM优化是正确的。 所以,我的问题是 - 它提议的重构绝对是一个无操作,因为JVM无论如何都会优化它,或者这里有一些微小的理论性能增益?
答案 0 :(得分:8)
我不会特别期望来优化它,不。
必须确保Collections.transform
永远不会隐藏Function
,并且该方法本身永远不会使this
可见等等。显然这一切都是可行的 - 但它可能是在极少数情况下,相对较小的收益可以做很多工作。
现在任何特定的虚拟机都没有经过仔细检查就很难说 - 但我认为“它不会显着影响性能”比“JVM优化它”更合理。
答案 1 :(得分:1)
是否将其提取到字段中应该真正取决于您调用它的频率以及父类持续多长时间。如果父类与应用程序一样长,并且你在蓝色的月亮中称这个东西一次,为什么还要为这样一个微不足道的操作而持有一个实例呢?相反,如果你经常调用这个东西,那么将它保存在变量中以节省创建多个对象的麻烦。
我认为我自己的经验法则是,如果内部类的范围在方法调用中,并且您的方法对性能不重要且实现很小,请将其保留在原来的位置。
答案 2 :(得分:0)
我认为JVM不会对其进行优化 - 可能,性能损失不值得优化成本。但是,内联代码的巨大好处远大于它。
答案 3 :(得分:-1)
如果要内联代码而不是每次都为Function创建对象,为什么不使用循环。你不会比那更有效率。但是,如果您想要可读性而不是性能(并且大多数时候这是一个更好的主意),您可以找到功能符号套件。
List<Bar> bars = new ArrayList<Bar>();
for(Foo foo: foos) {
// do some simple local transform of foo into a Bar.
bars.add(bar);
}
就个人而言,我觉得更简单。