代码之家  ›  专栏  ›  技术社区  ›  Jorjon

重新使用数组元素的最佳方法?

  •  0
  • Jorjon  · 技术社区  · 15 年前

    我有一个字符数组对象(扩展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;
        }
    }
    

    注意:charist是char类的静态成员。

    你有什么想法或更好的方法吗?

    谢谢!

    3 回复  |  直到 14 年前
        1
  •  2
  •   Juan Pablo Califano    15 年前

    我认为“优化的”版本不会优化太多。

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

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

    总之,我在代码中看到了两件可以轻松优化的事情:

    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对象本身。重新放置雪碧通常比创建新雪碧便宜。 你可以用一堆“死的”物体来处理这个问题,在你需要的时候,你可以从中取出一个,然后“把它带回到生活中”,而不是创建一个新的。

    本文讨论对象池(博客本身是ActionScript的好来源,特别是性能和数据结构主题;值得一看):

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

        2
  •  0
  •   z-boss    15 年前

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

        3
  •  0
  •   typeoneerror    15 年前

    是否有原因不能直接拼接出所需的字符并将新字符推送到数组中?

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

    如果您要通过引用查找存储,请签出AS3 Dictionary 对象或甚至闪存10的矢量(如果存储类型一致,则速度相当快):

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