ActionScript 3 Vector排序突然变得非常慢?

时间:2011-10-16 06:40:35

标签: flash actionscript-3 sorting

在玩'vector.sort()时我发现它在每种情况下都表现正常,除非需要对只有2或3个不同值的矢量进行排序。如果是这种情况,sort()函数运行速度非常慢。 这是我的代码:

var test:Vector.<int>=new Vector.<int>  ;
for (var i:int=0; i<6000; i++) {
    test.push(Math.floor(Math.random()*2));
}
var timer:Number
var timer2:Number
timer=new Date().getTime();
test.sort(compare)
timer2=new Date().getTime();
trace(timer2-timer)
function compare(x:int,y:int):Number {
    if (x>y) {
        return 1;
    } else if (x<y) {
        return -1;
    } else {
        return 0;
    }
}

只需复制此代码即可。 这可能是什么问题? 感谢。

2 个答案:

答案 0 :(得分:3)

我刚遇到同样的问题:在一个字段上有50,000个值对象的Vector.sort()有三个不同的值:~2分钟。然后我调用几乎完全相同的排序,唯一的区别是我在具有唯一值的辅助字段上打破平局(当x == y时)(也就是说,在具有50,000个不同值的字段上):超过1秒!这是用于说明我的意思的排序功能代码:

private function vastlyImprovedVectorSortFunc(x:MyVO, y:MyVO):Number
{
    if(x.fieldWithThreeValues > y.fieldWithThreeValues)
        return 1;
    else
        if(x.fieldWithThreeValues < y.fieldWithThreeValues )
            return -1;
        else
            if(x.uniqueFieldWithManyValues > y.uniqueFieldWithManyValues)
                return 1;
            else
                if(x.uniqueFieldWithManyValues < y.uniqueFieldWithManyValues )
                    return -1;
                else
                    return 0;
}

Bizarro世界,对吧?!看起来我要求函数做更多的工作,在一个非常独特的字段上应用二级排序 - 但显然Vector的排序函数性能会随着更少数量的不同排序“bins”而降低。当我在fieldWithAboutTwentyValues上对Vector进行排序时,我发现了这一点,并且性能仍然很差(约20秒),但是大大提高了。那时候在场上甚至更好,还有亚当的价值;所以我想,为什么不全力以赴,只对(独特的)主键做最后的排序。

改变游戏规则对我来说!希望它可以帮助别人。感到惊讶的是,这不是在某个地方的文档中。

答案 1 :(得分:2)

这实际上不会发生2或3个值,更准确地说,效果越明显,矢量中的不同值越少。每种排序算法都有它的缺点和优点。内置的(我认为它是冒泡排序)几乎是最糟糕的情况,当几乎没有明显的值。您可以尝试这种简单的替代方法(一种基数排序),但请注意它将具有更大的内存占用量,并且向量中的值越多,它们就越大。

package examples 
{
import flash.display.Sprite;

/**
 * An example for stackoverflow.com
 * @author wvxvw
 */
public class KindOfRadixSort extends Sprite
{

    public function KindOfRadixSort() 
    {
        super();
        this.test();
    }

    private function test():void
    {
        var test:Vector.<int> = new <int>[];
        var timer:Number;
        var timer2:Number;

        for (var i:int; i < 6000; i++) test.push(Math.random() * 5);

        timer = new Date().getTime();
        test.sort(compare);
        timer2 = new Date().getTime();
        trace(timer2 - timer); // 2488

        timer = new Date().getTime();
        this.kindOfRadixSort(test);
        timer2 = new Date().getTime();
        trace(timer2 - timer); // 3
    }

    private function compare(x:int, y:int):int
    {
        var result:int;
        if (x > y) result = 1;
        else if (x < y) result = -1;
        return result;
    }

    private function kindOfRadixSort(vector:Vector.<int>):Vector.<int>
    {
        // Arrays are sparse, therefore we don't allocate memory when having
        // gaps between filled indices as we would have we used vector.
        var cache:Array = [];
        var result:Vector.<int> = new <int>[];
        var i:int;

        for each (i in vector)
        {
            if (cache[i]) (cache[i] as Vector.<int>).push(i);
            else cache[i] = new <int>[i];
        }
        // A for-each loop could be better here, and, in fact, for-each on
        // arrays usually provides elements in order 0..length, however,
        // the specs say the order is undefined.
        for (i = cache.length - 1; i >= 0; i--)
        {
            if (cache[i] is Vector.<int>)
                result = (cache[i] as Vector.<int>).concat(result);
        }
        return result;
    }
}
}