当前位置: 首页 > 知识库问答 >
问题:

Java ArrayList与LinkedList的性能,仅与创建/插入和排序有关

耿敏达
2023-03-14

请考虑以下代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class testSortingSpeed {
    public static final int TOTAL_NUMBER = 10000000;

    public static void main(String[] args) {
        System.out.println("Creating ArrayList:");
        List<Pair<Integer, Integer>> a = new ArrayList<>();
        long start = System.currentTimeMillis();
        for (int i = 0; i < TOTAL_NUMBER; i++) {
            Pair<Integer, Integer> p = new Pair<>(
                (int ) Math.random() * TOTAL_NUMBER,
                (int ) Math.random() * TOTAL_NUMBER);
            a.add(p);
        }
        long end = System.currentTimeMillis();
        System.out.println("Time Elapsed = " + ((end - start) / 1000.0) + " seconds");
        System.out.println();

        System.out.println("Creating LinkedList:");
        List<Pair<Integer, Integer>> b = new LinkedList<>();
        start = System.currentTimeMillis();
        for (int i = 0; i < TOTAL_NUMBER; i++) {
            Pair<Integer, Integer> p = new Pair<>(
                (int ) Math.random() * TOTAL_NUMBER,
                (int ) Math.random() * TOTAL_NUMBER);
            b.add(p);
        }
        end = System.currentTimeMillis();
        System.out.println("Time Elapsed = " + ((end - start) / 1000.0) + " seconds");
        System.out.println();

        System.out.println("Sorting ArrayList:");
        start = System.currentTimeMillis();
        Collections.sort(a, Pair.LEXICOGRAPHIC_ORDER);
        end = System.currentTimeMillis();
        System.out.println("Time Elapsed = " + ((end - start) / 1000.0) + " seconds");
        System.out.println();

        System.out.println("Sorting LinkedList:");
        start = System.currentTimeMillis();
        Collections.sort(b, Pair.LEXICOGRAPHIC_ORDER);
        end = System.currentTimeMillis();
        System.out.println("Time Elapsed = " + ((end - start) / 1000.0) + " seconds");
        System.out.println();
    }
}

其中Pair是自定义定义的数据结构。

Pair<F, S> { F first; S second; }

上述程序的输出:Creating ArrayList:Time Elapsed=0.885秒

创建链接列表:已用时间 = 9.617 秒

排序数组列表:所用时间=0.128秒

对链接列表进行排序:已用时间 = 0.351 秒

我有点困惑,因为直觉上,LinkedList的创建应该比ArrayList更好。

对于排序,这是意料之中的,正如它在api:https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html中所说,Collections.sort将列表转储到ArrayList,对其进行排序,并将其转换回原始列表类型(对此不确定)

如果原始列表类型是ArrayList,我想可能会有优化。

共有1个答案

蔺翰音
2023-03-14

这将是特定于实现的,取决于ArrayList在您的平台上如何增长...但在大多数平台上,每当达到其容量时,它的大小就会增加1.5倍。

下面是JDK 1.8的代码:

/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

如果您将一千万个对象添加到一个空的ArrayList中,这个方法将被调用36次,ArrayList的默认初始容量是10。我在grow()和Arrays.copyOf()上进行了一些分析,它们非常快,即使对于大型数组也是如此。

另一方面,LinkedList需要为添加到它的每个元素分配一个新的Node对象——一千万次。这就是为什么LinkedList在这种情况下比较慢的原因。当您需要在列表的开头或中间插入或删除元素时,速度会快得多。

 类似资料:
  • 问题内容: 哪个实现不太“繁重”:PriorityQueue或排序的LinkedList(使用Comparator)? 我想对所有项目进行排序。插入将非常频繁,有时我将必须运行所有列表以进行一些操作。 问题答案: A 是最糟糕的选择。要么使用(或更一般地说,是一个实现者),要么。如果确实使用列表,则仅在遍历列表内容之前对其进行排序,而不是在每次插入之后对其进行排序。 有一点要注意的是,迭代器 不

  • 我有下面的代码,我在一个整数排序的LinkedList中插入了一个新的整数,但我不认为这是“正确”的方法,因为我知道,有指向下一个值的单LinkedList和指向下一个和上一个值的双LinkedList。我试图使用节点来实现以下情况,但Java正在导入这个导入组织。w3c。多姆。节点(文档对象模型)因此卡住了。 插入盒 > }

  • 我试图理解插入排序和选择排序之间的区别。 它们似乎都有两个组成部分:未排序列表和排序列表。它们似乎都从未排序列表中提取一个元素,并将其放在排序列表的适当位置。我看到一些网站/书籍说选择排序通过一次交换一个来实现这一点,而插入排序只是找到合适的位置并插入它。但是,我看到其他文章说了些什么,说插入排序也交换。因此,我感到困惑。有任何规范的来源吗?

  • 问题内容: 我建立了一个分析引擎,可以从数据库中提取50-100行原始数据(称为),在PHP上对其进行一堆统计测量,然后精确给出140个数据点,然后将它们存储在另一个表中(让我们称之为)。所有这些数据点都是非常小的整数(“ 40”,“ 2.23”,“-1024”是数据类型的很好的示例)。 我知道mysql的最大列数非常高(4000+),但是当性能真正开始下降时,似乎有很多灰色区域。 这里有一些关于

  • 本文向大家介绍Java中ArrayList和LinkedList的遍历与性能分析,包括了Java中ArrayList和LinkedList的遍历与性能分析的使用技巧和注意事项,需要的朋友参考一下 前言 通过本文你可以了解List的五种遍历方式及各自性能和foreach及Iterator的实现,加深对ArrayList和LinkedList实现的了解。下面来一起看看吧。 一、List的五种遍历方式

  • 我尝试在和中排序一个大小为100000000的数组,我可以看到它们之间存在巨大的性能差距。对于这个数字,几乎比快倍(在我的机器上)。 我记录了一些结果,发现当大小在10000左右或更小时,swift的速度更快,但一旦数值上升,就会变得比慢得多。 下面是Swift和Kotlin的代码, 迅捷 科特林 下面是两个记录的时间, 迅捷 因此,在这里,您可以看到在大小增加时变得极其缓慢,尽管在数量较小时它会