我应该避免在循环中获取集合的大小吗?
Should I Avoid Getting the Size of a Collection in a Loop?
根据第 3 处的 https://www.geeksforgeeks.org/12-tips-to-optimize-java-code-performance/,它说在 for 循环期间,您应该预先定义大小并在比较器中调用它。起初,假设 .size() 方法每次调用时都必须对元素进行计数,这对我来说是有意义的。
为了验证这一点,我查看了 ArrayList 的源代码并查看了 size 方法。但我发现它只是 return 一个整数大小,作为值存储在对象中。这更多的是我期待找到的东西,但如果是这样的话,那为什么文章说要避免呢?它没有解释为什么,它只是说永远不要这样做。据我所见,该列表已经在调用存储在内存中的变量。
所以,我的问题是:实际上 会有所帮助,还是只是文章有误?
是的,它实际上会有所帮助。
我认为调用一个方法比使用一个变量花费更多的时间。
答案是:“视情况而定”。
- 这取决于您使用的
List
class。
- 这取决于 JIT 编译器的智能程度。
- 这取决于在循环执行过程中列表的大小是否发生变化。
对于最常见的 List
实现,当前大小保存在一个字段中,而 size()
方法只是 returns 该字段。在这种情况下,size()
方法的代码通常会被内联,因此 size()
调用与直接访问该字段一样高效。如果 JIT 编译器能够推断出该字段没有改变(并且如果没有相关的 Java 内存模型相关约束)那么它可以想象将 size()
结果缓存在寄存器中。
但不利的一面是,某些 List
实现可能 计算 大小,而 JIT 编译器可能无法进行部分或全部优化。
但不利的一面是,如果 size()
很便宜,那么在每次循环迭代中调用它的开销可能太小而不重要。
底线:
谨防过早优化。
提防提供过于简单化/过于笼统建议的文章。
谨防包含 胡说八道 的文章,例如:
If possible, we can use primitive types instead of objects since data access from stack memory is faster than heap memory1.
1 - 这出现在 "5. 尽可能使用基本类型"。栈内存和堆内存使用相同的硬件,访问时间也相同。在这种情况下,他应该提出的真正要点是,与访问 int
.
相比,获取 Integer
的值涉及额外的内存获取
根据第 3 处的 https://www.geeksforgeeks.org/12-tips-to-optimize-java-code-performance/,它说在 for 循环期间,您应该预先定义大小并在比较器中调用它。起初,假设 .size() 方法每次调用时都必须对元素进行计数,这对我来说是有意义的。
为了验证这一点,我查看了 ArrayList 的源代码并查看了 size 方法。但我发现它只是 return 一个整数大小,作为值存储在对象中。这更多的是我期待找到的东西,但如果是这样的话,那为什么文章说要避免呢?它没有解释为什么,它只是说永远不要这样做。据我所见,该列表已经在调用存储在内存中的变量。
所以,我的问题是:实际上 会有所帮助,还是只是文章有误?
是的,它实际上会有所帮助。 我认为调用一个方法比使用一个变量花费更多的时间。
答案是:“视情况而定”。
- 这取决于您使用的
List
class。 - 这取决于 JIT 编译器的智能程度。
- 这取决于在循环执行过程中列表的大小是否发生变化。
对于最常见的 List
实现,当前大小保存在一个字段中,而 size()
方法只是 returns 该字段。在这种情况下,size()
方法的代码通常会被内联,因此 size()
调用与直接访问该字段一样高效。如果 JIT 编译器能够推断出该字段没有改变(并且如果没有相关的 Java 内存模型相关约束)那么它可以想象将 size()
结果缓存在寄存器中。
但不利的一面是,某些 List
实现可能 计算 大小,而 JIT 编译器可能无法进行部分或全部优化。
但不利的一面是,如果 size()
很便宜,那么在每次循环迭代中调用它的开销可能太小而不重要。
底线:
谨防过早优化。
提防提供过于简单化/过于笼统建议的文章。
谨防包含 胡说八道 的文章,例如:
If possible, we can use primitive types instead of objects since data access from stack memory is faster than heap memory1.
1 - 这出现在 "5. 尽可能使用基本类型"。栈内存和堆内存使用相同的硬件,访问时间也相同。在这种情况下,他应该提出的真正要点是,与访问 int
.
Integer
的值涉及额外的内存获取