在对象上调用getter而不是将其存储为局部变量(内存占用,性能)

Kaw*_*awu 30 java performance readability memory-consumption

在下面的代码中,我们进行了listType.getDescription()两次调用:

for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
    if (listType.getDescription() != null)
    {
        children.add(new SelectItem( listType.getId() , listType.getDescription()));
    }
}
Run Code Online (Sandbox Code Playgroud)

我倾向于重构代码以使用单个变量:

for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
    String description = listType.getDescription();

    if (description != null)
    {
        children.add(new SelectItem(listType.getId() ,description));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的理解是JVM以某种方式针对原始代码进行了优化,尤其是嵌套调用children.add(new SelectItem(listType.getId(), listType.getDescription()));.

比较两个选项,哪一个是首选方法,为什么?这就是内存占用,性能,可读性/易用性以及其他我现在不想到的内容.

后一个代码片段何时变得比前者更有利,也就是说,listType.getDescription()当使用临时局部变量变得更加理想时,是否存在任何(近似)调用次数,因为listType.getDescription()总是需要一些堆栈操作来存储this对象?

maa*_*nus 33

我几乎总是喜欢局部变量解决方案.

内存占用

单个局部变量需要4或8个字节.它是一个参考,没有递归,所以让我们忽略它.

性能

如果这是一个简单的getter,JVM可以自己记忆,所以没有区别.如果这是一个无法优化的昂贵电话,手动记忆会使其更快.

可读性

遵循DRY原则.在你的情况下,它几乎不重要,因为局部变量名称与字符方式一样,只要方法调用,但对于任何更复杂的,它的可读性,因为你不必找到两个表达式之间的10个差异.如果您知道它们是相同的,那么使用局部变量清楚地表明它们.

正确性

想象一下,你SelectItem不接受nulls,你的程序是多线程的.listType.getDescription()在此期间,价值可能会发生变化而你会被烘烤.

调试

拥有包含有趣值的局部变量是一个优点.


通过省略局部变量来获胜的唯一方法就是保存一行.所以我只会在无关紧要的情况下这样做:

  • 很短的表达
  • 没有可能的并发修改
  • 简单的私人最后的getter

  • 关于“正确性”部分下的多线程问题的重点。谢谢! (3认同)

Pet*_*sik 7

我认为第二种方式肯定更好,因为它提高了代码的可读性可维护性,这是最重要的事情.除非您编写每毫秒重要的应用程序,否则这种微优化不会对您有任何帮助.