Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java性能:获取和设置列表_Java_Performance - Fatal编程技术网

Java性能:获取和设置列表

Java性能:获取和设置列表,java,performance,Java,Performance,有谁能告诉我,这两种方法中的任何一种是否比在Java1.6下编译的另一种性能更好?假设MyObject是一个类,它有一个名为listField的字段,该字段有一个getter和setter 样本#1: MyObject obj=新的MyObject(); 列表lst=新阵列列表(1); 第1条添加(“Foo”); 对象设置列表字段(lst); 样本#2: MyObject obj=新的MyObject(); 对象setListField(新ArrayList(1)); obj.getListF

有谁能告诉我,这两种方法中的任何一种是否比在Java1.6下编译的另一种性能更好?假设MyObject是一个类,它有一个名为listField的字段,该字段有一个getter和setter

样本#1:

MyObject obj=新的MyObject();
列表lst=新阵列列表(1);
第1条添加(“Foo”);
对象设置列表字段(lst);
样本#2:

MyObject obj=新的MyObject();
对象setListField(新ArrayList(1));
obj.getListField().add(“Foo”);

我的想法是,创建ArrayList的本地实例将产生内存开销,但无论何时要添加到列表中,调用getListField()都不如访问列表的本地版本快。也许如果列表中要添加多个项目,那么样本1会更快,但如果只有几个项目,样本2会更快?或者编译器会对此进行优化,以便调用getListField()相当于访问列表的本地版本吗?

没有“本地实例”这样的东西。假设
setListField()
getListField()
都是微不足道的方法,那么这些示例之间应该没有什么性能差异(如果有的话)。假设您使用的是HotSpot,并且没有加载覆盖setListField或getListField的子类,我希望这些方法是内联的

您需要了解,当您调用
setListField()
(再次假设它是一个简单的实现)时,您并不是在创建列表的副本,或者类似的东西。您只是在传递对列表对象的引用。然后将该引用复制到字段中。非常便宜。同样地,我希望
getListField()
只返回字段的值-对列表的引用。唯一被复制的是引用—可能是4或8字节,这取决于您的JVM


就我个人而言,第一个示例看起来更干净,但你应该专注于理解这里发生的事情,这是一个比性能更重要的问题。

IMO编译器将足够聪明,可以优化这两个示例,并且不会产生任何差异。

Cameron


为什么要创建ArrayList并将其显式调整为1个元素?如果列表中的元素永远不会超过1个,请不要使用列表——如果会,则列表的大小会影响您的性能。你提出的问题,IMHO,是一个非问题。

我认为要考虑的是,为什么要创建一个只有一个元素的数组列表。这样,当向该列表中添加新元素时,内部数组将不得不扩展,我认为它会更糟。


默认情况下,
ArrayList
s设置为10个元素。

相同数量的新元素=>相同的性能


您不应该担心这一点,除非评测显示这是一个瓶颈

显然是过早的优化。选择更具可读性的选项。局部变量不需要任何成本。一旦代码被编译成本机语言,它们通常不会消耗任何内存。(而且,只要代码仍然得到解释,就显然不足以以任何方式进行优化。)Jon,显式ArrayList大小设置为1怎么样?当然,这会引起问题。顺便说一句,你是我的英雄。@Amir:这只是初始容量。为什么会有问题?事实上,列表中只有一项。是的,将第二项添加到列表会导致它调整大小(如果列表构造函数没有强制执行最小值;我没有检查),但我认为这超出了这个问题的范围。您是对的,ArrayList将被分配,无论它是否立即设置在MyObject对象上。我真傻。关于getListField()只是返回一个内存引用,假设我需要将一个名为myArray的字符串数组复制到MyObject对象的listField字段,而不是1个项,该数组可以包含数百个项。调用obj.getListField().add(myArray[i])数百次会比调用lst.add(myArray[i])然后在myObject上设置lst慢吗?看起来一个方法调用的开销至少会有一些影响。@Cameron:实际上可能不会,因为JIT编译器可能会将其内联。很难说,但它几乎肯定不会成为代码中的瓶颈。这很重要:首先编写最干净的代码,并衡量其性能。如果你发现一个瓶颈,就对它进行微优化。我正在初始化列表,这样就不会有人指出我应该初始化列表大小。在我的真实场景中,列表大于1,我将其初始化为1。
MyObject obj = new MyObject();
List<String> lst = new ArrayList<String>(1);
lst.add("Foo");
obj.setListField(lst);
MyObject obj = new MyObject();
obj.setListField(new ArrayList<String> (1));
obj.getListField().add("Foo");