【发布时间】:2013-06-07 05:26:15
【问题描述】:
在kjellkod's article 中提到,如果我们在接收List 作为参数的方法中传递ArrayList,那么我们会损失性能,因为ArrayList 实现了额外的RandomAccess 接口。
文章示例:
// SLOWER: as shown in http://ideone.com/1wnF1
private static void linearInsertion(Integer[] intArray, List<Integer> list) {
[...]
int list_size = list.size();
for (int i = 0; i < list_size; i++) {
if (integer.compareTo(list.get(i)) >= 0) { // ... more code
// FASTER: as shown in http://ideone.com/JOJ05
private static void linearInsertion(Integer[] intArray, ArrayList<Integer> list) {
[...]
int list_size = list.size();
for (int i = 0; i < list_size; i++) {
if (integer.compareTo(list.get(i)) >= 0) { // ... more code
来自参考:
鼓励通用列表算法检查给定列表是否 在应用算法之前是此接口的一个实例 如果将其应用于顺序,将提供较差的性能 访问列表,并在必要时更改其行为以保证 可接受的性能。
但是,如果我们真的在上述方法中传递 ArrayList 并检查list instanceof RandomAccess,那么这两种情况都是如此。
那么,我的第一个问题是为什么 Java VM 应该在第一种方法中将其解释为顺序列表?
我已经修改了文章中的测试来检查我机器上的这种行为。在ideone 上运行测试时,它显示的结果类似于 kjellkod 的结果。但是当我在本地运行它时,我得到了意想不到的结果,这与文章解释和我的理解相反。在我的例子中,ArrayList as List 迭代似乎比将它引用为 ArrayList 快 5-25%:
如何解释这种差异? 是否取决于架构或处理器内核数量?我的工作机器配置是 Windows 7 Professional x64、Intel Core i5-3470(4 核、4 线程)、16 GB RAM。
【问题讨论】:
-
这篇文章对我来说没有意义......当你遍历一个列表时,调用的方法是使用的具体实现,而不是随机的低效实现。
-
使用
-XX:LogCompilation运行 java 将记录 JIT 优化,您可能会注意到一些差异。 -
BTW Gb = 千兆位,GB = 千兆字节。
标签: java time arraylist iteration random-access