【问题标题】:Custom Iterator is slow自定义迭代器很慢
【发布时间】:2017-02-03 13:19:32
【问题描述】:

我一直在尝试衡量我的自定义迭代器在一个简单的 int 数组上的性能。真的很简单,如下图:

class IntArrayIterator_NoCheck implements Iterator<Integer> {

    private final int[] array;
    private int counter = 0;

    public IntArrayIterator_NoCheck( int[] array ) {
        this.array = array;
    }

    @Override
    public boolean hasNext() {
        return counter < array.length;
    }

    @Override
    public Integer next() {
        return array[counter++];
    }

}

将它与 ArrayList 迭代器和 Trove (http://trove.starlight-systems.com/) 进行比较后,我发现了奇怪的结果。测试按以下方式进行:

  • 100000 个随机 int 元素的列表/数组
  • 热身
    • 10000x 迭代整个集合
    • 10000x 再次遍历整个集合
  • 测试
    • 10000x 迭代整个集合,通过 System.nanoTime 和 ThreadMXBean.getCurrentThreadCpuTime() 测量

Trove TIntArrayList 迭代器是最快的迭代器,运行时间为 30 毫秒。 Java ArrayList 迭代器的运行时间为 85 毫秒。简单 int 数组上的自定义迭代器有 320 毫秒的运行时间!

我的自定义迭代器性能糟糕的可能原因是什么?在查看 ArrayList 和 TIntArrayList 迭代器实现之后,它们要复杂得多(执行更多操作),因此我不明白为什么它更快。谁能给我解释一下?

【问题讨论】:

标签: java performance iterator


【解决方案1】:

您的next 方法将产生与

相同的字节码
public Integer next() {
    return Integer.valueOf(array[counter++]);
}

请注意,对于任何超出缓存值范围的int(仅保证为-128127),都会创建一个新的Integer 对象。

ArrayList 不会发生这种情况,因为转换发生在将 Integers 存储在列表中之前。
TArrayList 具有返回原始类型 inta custom iterator type,这不需要Integer 对象的创建。

【讨论】:

  • 谢谢!我根本没有意识到这一点。
【解决方案2】:

你有一个 Integer 的迭代器,但是你使用的是一个 int 的数组。

因此,您在迭代时会不断地拆箱。你懂的;将 Integer 转换为 ints 并返回是一项昂贵的操作;每次迭代都这样做会害死你。

因为每次调用 next 都意味着将 int 装入 Integer。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2013-09-02
    相关资源
    最近更新 更多