Mar*_*rty 8 memory performance actionscript-3 avm2
在我的游戏引擎中,我使用Box2D进行物理.Box2D的命名惯例和糟糕的评论破坏了我的引擎的一致且记录良好的剩余部分,这有点令人沮丧并且当你使用它时表现不佳.
我考虑过为Box2D制作一套包装类.也就是说,扩展每个常见Box2D对象并重写其功能的类遵循我的引擎其余部分的命名约定,并使它们更清晰,更一致地进行评论.我甚至考虑构建一些类的ontop并添加一些零碎(比如b2Vec2类中的基于像素的测量的getter ).
这很好,但我不能100%确定这会产生什么负面影响以及这些影响我应用程序和游戏的程度.我不确定编译器是否在一定程度上减轻了我的一些顾虑,或者为了可读性和一致性而添加一些不必要的类时我是否需要考虑周全.
我有一些怀疑:
我特别询问运行时影响.
在集成第三方库时,这是一个非常常见的问题,尤其是作为端口的库(如Box2DAS3),它们保留了母语的编码和命名约定,而不是与目标语言完全集成(例如:Box2DAS3使用getFoo()而setFoo()不是.foogetter/setter).
要快速回答您的问题,不会,制作包装类不会对性能产生重大影响; 只不过你将在自己的项目中的类层次结构中看到.当然,如果你计算500万次迭代的循环,你可能会看到一两毫秒的差异,但在正常使用中,你不会注意到它.
"更多的内存消耗,以适应更高级别的类结构." 就像任何具有类继承性的语言一样,vtable将在幕后使用,因此你的内存/性能会略有增加,但它可以忽略不计.
"由于初始化更多级别的成员而在创建新对象时会对性能产生影响?" 只不过是正常的实例化,所以除非你创造了大量的对象,否则不用担心.
性能方面,你通常应该没有问题(除了你实际上有问题之外,有利于可读性和可用性而不是性能),但我更多地将它看作是一个架构问题,考虑到这一点,我会考虑什么扩展/修改外部库类的负面影响通常分为3个区域,具体取决于您要执行的操作:
修改库
由于Box2DAS3是开源的,所以没有什么能阻止你跳入并重构所有类/函数名称到你的内容.我有时认真考虑这样做.
优点:
缺点:
扩展课程
在这里,您只需创建自己的包装类,它们扩展了基本的Box2D类.您可以根据需要添加属性和函数,包括实现自己的命名方案,该方案转换为基类(例如,MyBox2DClass.foo()可以简单地作为包装器Box2DClass.bar())
优点:
MyBox2DClass对象传递给内部方法,该方法需要一个Box2DClass并且您知道它将工作缺点:
setPos()还是SetPosition()?).即使你自己工作,当你在6个月内回到你的班级时,你会忘记的setPos()),而其他函数使用Box2D(SetPosition()))与您自己的课程组成
你创建自己的类,在内部持有Box2D属性(例如MyPhysicalClass将具有属性b2Body).您可以根据需要自由实现自己的界面,并且只需要实现.
优点:
b2Body属性的Box2DComponent缺点:
在这三者中,我更喜欢使用组合,因为它提供了最大的灵活性并保持引擎的模块化特性,即您拥有核心引擎类,并且您可以使用外部库扩展功能.您可以用最少的工作量切换库这一事实也是一个巨大的优势.这是我在自己的引擎中使用的技术,我也将它扩展到其他类型的库 - 例如广告 - 我有我的引擎广告类,可以根据需要与Mochi,Kongregate等集成 - 我的游戏的其余部分并不关心我正在使用什么,这让我在整个引擎中保持我的编码风格和一致性,同时仍然灵活和模块化.
-----更新2013年10月9日-----
大更新时间!所以我回去做一些关于尺寸和速度的测试.我使用的课程太大而无法在此处粘贴,因此您可以在http://divillysausages.com/files/TestExtendClass.as下载它.
在其中,我测试了许多类:
Empty例子; 一个只扩展Object并实现空getPostion()函数的类.这将是我们的基准b2Body实例Box2DExtends例子; 一个扩展b2Body并实现一个getPosition()只返回GetPosition()的b2Body函数的类(函数)Box2DExtendsOverrides例子; 扩展b2Body和覆盖GetPosition()函数的类(它只返回super.GetPosition())Box2DComposition例子; 一个具有b2Body属性和getPosition()返回函数的函数的类b2Body's GetPosition()Box2DExtendsProperty例子; 扩展b2Body并添加新Point属性的类Box2DCompositionProperty例子; 具有b2Body财产和Point财产的类所有测试均在独立播放器FP v11.7.700.224,Windows 7上,在不太好的笔记本电脑上完成.
测试1:大小
AS3有点烦人,如果你调用getSize()它,它会给你对象本身的大小,但任何内部属性也Objects只会导致4 byte增加,因为它们只计算指针.我可以看出为什么他们这样做,只是让得到合适的尺寸有点尴尬.
于是我转向flash.sampler包裹.如果我们对对象的创建进行采样,并在对象中添加所有大小NewObjectSample,我们将获得对象的完整大小(注意:如果您想查看创建的内容和大小,log请在测试中调用注释文件).
这些大小都是以字节为单位.一些值得注意的要点:
Object大小是40字节,所以只是类,没有别的是16字节.20字节和指向属性的指针Box2DComposition164b2BodyBox2DExtendsProperty等你16的Point类本身,4对于指向Point特性,并8为每个x和y财产Numbers= 36这之间的差异字节Box2DExtends显然,大小的差异取决于你添加的属性,但总而言之,几乎可以忽略不计.
测试2:创作速度
为此,我简单地使用getTimer()循环10000,循环10(如此100k)次以获得平均值.System.gc()在每组之间调用以最小化由于垃圾收集而导致的时间.
这里没有一大堆需要注意.扩展/组合类需要稍微长一点,但它就像0.000007ms(这是100,000个对象的创建时间),所以它不值得考虑.
测试3:通话速度
为此,我getTimer()再次使用循环1000000,循环10(因此10米)以获得平均值.System.gc()在每组之间调用以最小化由于垃圾收集而导致的时间.所有对象都getPosition()/GetPosition()调用了它们的函数,以查看覆盖和重定向之间的区别.
这个让我感到有些惊讶,时间之间的差异是2倍(虽然这仍然是0.000007ms每次通话).延迟似乎完全取决于类的继承 - 例如Box2DExtendsOverrides简单地调用super.GetPosition(),但速度是从其基类Box2DExtendsProperty继承的两倍GetPosition().
我想这与函数查找和调用的开销有关,虽然我看一下在swfdumpFlexSDK中使用生成的字节码,它们是相同的,所以它对我说谎(或者不包括它),或者有一些我缺少的东西:)虽然步骤可能是相同的,但它们之间的时间可能不同(例如在内存中,它跳到你的类vtable,然后跳到基类vtable等)
字节码var v:b2Vec2 = b2Body.GetPosition()只是:
getlocal 4
callproperty :GetPosition (0)
coerce Box2D.Common.Math:b2Vec2
setlocal3
Run Code Online (Sandbox Code Playgroud)
而var v:b2Vec2 = Box2DExtends.getPosition()(getPosition()返回GetPosition())是:
getlocal 5
callproperty :getPosition (0)
coerce Box2D.Common.Math:b2Vec2
setlocal3
Run Code Online (Sandbox Code Playgroud)
对于第二个例子,它没有显示调用GetPosition(),所以我不确定他们是如何解决的.如果有人想解释它,可以下载测试文件.
要记住一些要点:
GetPosition()什么都不做; 它本质上是一个伪装成功能的吸气剂,这是"额外阶级惩罚"显得如此之大的一个原因总而言之,我希望通过扩展我自己的一个类来获得相同的结果,所以我不会真的担心它.实施最适合您的解决方案的架构.