在ActionScript 3中扩展类有什么负面影响?

时间:2013-09-13 00:39:32

标签: performance actionscript-3 memory avm2

在我的游戏引擎中,我使用Box2D进行物理学处理。 Box2D的命名惯例和糟糕的评论破坏了我的引擎的一致且记录良好的剩余部分,这有点令人沮丧,当你使用它时表现不佳。

我考虑过为Box2D制作一套包装类。也就是说,扩展每个常见Box2D对象并重写其功能的类遵循我的引擎其余部分的命名约定,并使它们更清晰,更一致地进行评论。我甚至考虑构建一些类的ontop并添加一些零碎(比如b2Vec2类中基于像素的测量的getter。)

这很好,但我不能100%确定这会产生什么负面影响以及这些影响我应用程序和游戏的程度。我不确定编译器是否在一定程度上缓解了我的一些问题,或者为了可读性和一致性而添加一些不必要的类时我是否需要考虑周全。

我有些怀疑:

  • 更多的内存消耗,以适应更高级别的类结构。
  • 由于初始化额外级别的成员而在创建新对象时的性能影响?

我特别询问运行时影响。

4 个答案:

答案 0 :(得分:1)

我知道这个答案不符合赏金的条件,因为我懒得写基准。但是,在使用Flash代码库之后,我可能会给出一些提示:

avm2是一种动态语言,因此在这种情况下编译器不会优化任何内容。 将呼叫包装为子类呼叫将产生费用。然而,这个成本将是恒定的时间和小。

对象创建成本最多也会受到恒定时间和内存的影响。与基本成本相比,时间和数量可能是微不足道的。

但是,正如许多事情一样,魔鬼在细节中。我从来没有使用过box2d,但如果它有任何类型的对象池,那么事情可能就不再适用了。一般来说,游戏应该尝试在游戏时没有对象分配的情况下运行。所以要非常小心,不要添加分配对象的函数,只是为了更漂亮。

function addvectors(a:vec,b:vec,dest:vec):void

可能很丑,但比

快得多
function addvectors(a:vec,b:vec):vec

(我希望我的AS3语法正确......)。更有用也可能更丑陋

function addvectors(a:Vector.<vec>, b:Vector.<vec>, dest:Vector.<vec>, offset:int, count:int):void

所以我的答案是,如果你只是为了可读性而包装,那就去吧。这是一个小但不变的成本。但要非常非常小心地改变功能的运作方式。

答案 1 :(得分:0)

我不知道对于实例时间是否会产生很大影响,但我会以不同的方式回答您的问题:您还有其他选择吗?他们似乎会做得更好吗?

Jackson Dunstan对功能表现有一个很好的基准:http://jacksondunstan.com/articles/1820

总结一下:

所以,如果你不想使用继承,也许你必须用静态调用替换它,这对性能有害。 就个人而言,我将扩展这些类并添加我在运行时需要的所有对象的急切实例:如果它很大,那就制作一个漂亮的加载屏幕......

另外,请看一下post字节码优化,例如apparat:http://code.google.com/p/apparat/

答案 2 :(得分:0)

我认为延伸不会对性能产生太大影响。是的,有一些成本,但只要你不使用成分就不会那么高。即而不是直接扩展Box2d类,您可以创建该类的实例并在类中使用它。例如这个

public class Child extends b2Body {
    public function Child() {
        // do some stuff here
    }
}

而不是

public class Child  {
    private var _body:b2Body;
    public function Child() {
        ...
        _body = _world.CreateBody(...);
        ...
    }
}

我想你知道,因为你创建的对象越少越好。只要保留已创建实例的数量,您将获得相同的性能。

从另一个角度来看: a)再添加一层抽象可能会改变Box2d。如果您在团队中工作,这可能是一个问题,因为其他开发人员应该了解您的命名 b)小心中间人代码气味。通常,当您开始包装现有功能时,您最终会得到只是委托人的类。

答案 3 :(得分:0)

这里有一些很好的答案,但我要把两分钱扔进去。

您必须识别两个不同的概念:扩展类时以及实现类时。

以下是扩展MovieClip

的示例
public class TrickedOutClip extends MovieClip {
   private var rims = 'extra large'
   public function TrickedOutClip() { 
     super();
   }
}

以下是实现MovieClip

的示例
public class pimpMyClip {
   private var rims = 'extra large';
   private var pimpedMovieClip:MovieClip;
   public function pimpMyClip() { 
     pimpedMovieClip = new MovieClip();
     pimpedMovieClip.bling = rims;
   }

 public function getPimpedClip() { 
     return pimpedMovieClip;
   }
}

我认为你可能不想扩展这些box2D类但是要实现它们。这是一个粗略的大纲:

 public class myBox2DHelper {
   private var box2d = new Box2D(...);

  public function MyBox2DHelper(stage) {

  }

   public function makeBox2DDoSomeTrickyThing(varA:String, varB:Number) { 
       // write your custom code here
     }

   public function makeBox2DDoSomethingElse(varC:MovieClip) { 
       // write your custom code here
     }
  }
祝你好运。