【问题标题】:Why StringBuilder append() faster than LinkedList add()?为什么 StringBuilder append() 比 LinkedList add() 快?
【发布时间】:2015-07-30 07:41:00
【问题描述】:

我正在尝试基于 LinkedList 结构创建新的 StringBuilder。

如您所知,Java 的 StringBuilder append() 操作类似于数组列表 add() 操作(超出容量时调整值数组的大小)。

我意识到插入String时,StringBuilder.append()LinkedList.add()

(*这是一个纯粹的列表添加过程)。

这里是sn-p的代码:

        List<String> linkedList = new LinkedList<>();
        StringBuilder stringBuilder = new StringBuilder();

        int loopCount = 5_000_000;

        long s, e;

        s = System.currentTimeMillis();
        for (int i = 0; i < loopCount; i++) {
            linkedList.add(UUID.randomUUID().toString() + "\n");
        }
        e = System.currentTimeMillis();
        System.out.println("LinkedList: "+(e - s));

        s = System.currentTimeMillis();
        for (int i = 0; i < loopCount; i++) {
            stringBuilder.append(UUID.randomUUID().toString() + "\n");
        }
        e = System.currentTimeMillis();
        System.out.println("String Builder: " + (e - s));

这些是基准测试结果。(基于 500 万次插入)

StringBuilder: 13892 millisec
LinkedList:    19561 millisec

我还用 ListIterator.add() 更改了 add() 方法,但我没有更改任何内容。

这是我的问题:我怎样才能使 list add() 方法变得比StringBuilder.append() 更快?

【问题讨论】:

  • 您应该对此类测试使用微基准测试。另外,您正在将苹果与梨进行比较... StringBuilder 不是列表, LinkedList 不是字符串生成器。所以我看不出你想要做什么的意义......
  • “如你所知,Java 的 StringBuilder 类就像数组列表一样工作。” 不,我不知道。事实上,我对此表示严重怀疑。
  • 你试过ArrayList吗?除非必须增加后备阵列容量(不应该太频繁),否则插入 ArrayList 应该比插入 LinkedList 更快。
  • 您的基准测试可能会给出不可靠的结果,因为 JIT 编译器可能会选择优化死代码。另请参阅avoiding benchmarking pitfalls in the JVM
  • 我知道这不是列表实现,我正在尝试创建新的 StringBuilder,如基于 LinkedList 算法的 String concat 数据结构。Java 的 StringBuilder 像 ArrayList 一样工作。所以我认为 new StringBuilder 可以像 LinkedList 和 concat 一样工作列表中的所有字符串。所以可能比 Java 的 StringBuilder 更快。

标签: java algorithm collections linked-list stringbuilder


【解决方案1】:

当您向LinkedList 添加项目时,会创建新的Node 对象

void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

Node 对象包含对下一个和上一个节点的引用。

StringBuilder 通过原生 System.arraycopy 将字符串字符附加到底层数组,因此不会创建任何实例。

这可能会影响创建多个这些 Node 实例的时间。

【讨论】:

    猜你喜欢
    • 2014-02-21
    • 2014-07-08
    • 2014-04-21
    • 2017-11-04
    • 2021-12-19
    • 1970-01-01
    • 2012-10-16
    • 2011-09-04
    • 2011-08-24
    相关资源
    最近更新 更多