当阵列速度更快时,为什么要使用列表?

时间:2016-04-29 13:04:24

标签: arrays performance list haxe

我注意到Arrays的执行速度远远超过Haxe的链接列表(至少在cpp上)。我得到的结果如下。

Main.hx:40: With 1 items, Array is 14% faster than List.
Main.hx:40: With 5 items, Array is 58% faster than List.
Main.hx:40: With 10 items, Array is 59% faster than List.
Main.hx:40: With 100 items, Array is 54% faster than List.
Main.hx:40: With 1000 items, Array is 56% faster than List.
Main.hx:40: With 10000 items, Array is 55% faster than List.
Main.hx:40: With 100000 items, Array is 52% faster than List.

这令我感到尴尬。尽管Array必须不断复制项目,但Array怎么能这么快?为什么甚至使用Lists呢?

package tests;

import haxe.Timer;

class Main 
{

    static function main() 
    {
        var arr:Array<Int> = new Array();
        var list:List<Int> = new List();
        var result = new List();

        for (items in [1, 5, 10, 100, 1000, 10000, 100000]) {
            var listtime = timeit(10000, function() {
                for (i in 0...items)
                    list.add(i);
                for (x in list)
                    result.add(x);
                result.clear();
                list = new List();
            });

            var arrtime = timeit(10000, function() {
                for (i in 0...items)
                    arr.push(i);
                for (x in arr)
                    result.add(x);
                result.clear();
                arr = new Array();
            });

            if (arrtime < listtime)
                trace('With $items items, Array is ${Std.int((1-arrtime/listtime)*100)}% faster than List.');
            else
                trace('With $items items, List is ${Std.int((1-listtime/arrtime)*100)}% faster than Array.');
        }
    }

    static public function timeit<T>(times:Int, f:Void -> T):Float {
        var start = Timer.stamp();
        for (i in 0...times) {
            f();
        }
        var time = Timer.stamp() - start;
        return time;
    }

}

3 个答案:

答案 0 :(得分:7)

  

即使必须不断复制项目,数组如何才能如此快速?

对于线性处理,数组更快,因为数组内容连续存储在内存中。当您以线性方式访问内存时,会同时将多个对象提取到处理器缓存中。另一方面,链接列表节点分散在整个存储器中,因此线性处理它们会导致主存储器中的更多访问。读取缓存比读取主内存要快得多。

  

为什么甚至使用Lists呢?

使用链表的一个主要原因是插入新元素或删除现有元素不会使链接列表中其他元素的引用(包括迭代器和指针)无效。数组不能有这样的保证。

答案 1 :(得分:4)

  

为什么在阵列更快时使用列表?

更快的是什么?链接列表在其他人之间插入元素或删除列表中间的元素时通常要快得多。对于位置i插入或删除的数组(至少是C样式数组),需要在i之后移动每个元素。使用链接列表,您只需要更改几个指针。

再次尝试测试,但不要将元素推到列表的末尾,而是将它们插入开头。

答案 2 :(得分:3)

有一篇文章广泛讨论了这个问题:

https://github.com/delahee/haxe.opt/blob/master/list_vs_array.md

TLDR:这取决于你的用例,但在某些情况下列表肯定会更快。