重用Array中元素的最佳方法?

时间:2009-06-26 02:29:10

标签: actionscript-3 arrays object

我有一个Character对象数组(扩展Sprite)。

public static var charlist:Array;

当一个角色死亡时,我会设置一个标志来表示。

char.die = true;

当我产生一个新玩家时,我会检查这个标志,重新使用该插槽。这就是问题所在。 最好的方法是什么?其实我有这种方法:

char = new Char();
/* ... */
for (var i:Number = 0; i < Char.charlist.length; i++) {
    if (Char.charlist[i].death) {
        Char.charlist[i] = char;
        return;
    }
}

但问题是我来自C ++,我认为每次迭代计算索引都是浪费 我会这样做,但这在AS3中不起作用,因为我无法通过引用访问项目:

char = new Char();
/* ... */
for (var i:Number = 0; i < Char.charlist.length; i++) {
    var char_it:Char = Char.charlist[i];
    if (char_it.death) {
        char_it = char;
        return;
    }
}

注意:charlist是Char类的静态成员。

您有任何想法或更好的方法吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

我认为“优化”版本的优化程度不高。

您的代码在每次迭代中都不会执行2次访问。当你碰巧找到一个死的Char时它就会发生;然后你回来了。所以,我认为没什么大不了的。

就个人而言,我认为重用阵列插槽也不会产生很大的影响。并且,它可能会降级(但最糟糕的是,如果你避免它,你的代码会更简单)。假设你有100个字符,其中60个已经死了,你有一个循环,每个帧运行并对每个实时字符执行一些检查/操作。你可以循环超过100个字符,如果你保留了一个活动对象列表和一个死对象的separte列表,你可以循环超过40个字符,准备重用它们。此外,“死列表”可以作为堆栈处理,因此不需要迭代来获取char。

无论如何,我看到你可以在代码中轻松优化的两件事:

1)检索循环外的列表长度:

这样做:

var len:int = Char.charlist.length;
for (var i:Number = 0; i < len; i++) {

而不是:

for (var i:Number = 0; i < Char.charlist.length; i++) {

编译器不会优化调用长度(遵循ecmascript规范)。

2)避免静态访问(对于charlist)。众所周知,它比实例访问慢得多。

修改

重新阅读你的问题,我意识到我误解了它的一部分。您不是要重用Char对象,而是重用阵列插槽。不过,我不认为重用数组插槽是值得的(Actionscript中的数组是不固定的);但是可以帮助提高性能的东西就是重用Char对象本身。重新设置Sprite通常比创建一个Sprite便宜。 您可以通过一组“死”对象来管理它,您可以从中获取一个并在需要时“恢复生命”,而不是创建一个新对象。

这篇文章讨论了对象池(博客本身是Actionscript的一个很好的来源,特别是对于性能和数据结构主题;值得一看):

http://lab.polygonal.de/2008/06/18/using-object-pools/

答案 1 :(得分:0)

为什么不使用列表而不是数组,只需从列表中删除死的列表并在需要时添加新的列表? 是否有充分理由尝试重复使用插槽?
你想要优化什么?

答案 2 :(得分:0)

有没有理由你不能拼出所需的角色并将新角色推到阵列上?

var characters:Array = ["leo", "raph", "don", "mike"];
characters.splice(1, 1);
trace(characters);
characters.push("splinter");
trace(characters);

如果您正在通过引用查找存储,请检查AS3的Dictionary对象,甚至是Flash 10的Vector(如果存储类型一致;速度非常快):

http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html