C#-降低Monotouch中本机<->托管交互的成本
作者:互联网
我正在玩一个本机库,我为该库编写了monotouch(我们现在应该将其命名为Xamarin.iOS?)绑定.
即使函数的核心不执行任何操作或返回base.X(),覆盖C#中的某些常用方法仍会严重降低性能.仪器确认问题以及在管理的本地交互中花费的时间.
有没有办法从一侧或另一侧(本机或受控)加快速度?还是在MT中进行P / Invoking时要缴纳的税款?
我碰到的玻璃天花板大约是50000个呼叫/秒.
[2013/02/22更新]
为了给出一些背景或示例,这是我正在做的事情.我正在玩cocos2d运动学(没有花栗鼠).为了管理自己的精灵位置,我必须重写
CGAffineTransform NodeToParentTransform { get; }
和
bool Dirty { get; }
前者返回一个矩阵,并戳本地面以获得诸如ScaleX,ScaleY,RotationX之类的参数. RotationY和AnchorPointInPoints,后者无条件返回true.
我目前降低成本的尝试在某种程度上是成功的,因为通过将本机代码更改为单点覆盖(不戳任何属性),可以使速度提高25%到50%.
-(BOOL) dirty:(CGAffineTransform*)nodeToParentTransform rotationX:(float)rotX rotationY:(float)rotY scaleX:(float)scaleX scaleY:(float)scaleY anchorPointInPoints:(CGPoint)anchorPointInPoints;
现在,我的3500个Sprite的速度几乎达到了25-30fps,但我仍然想走得更远.并且也不必修补本机源.
[更新2013/02/22 2]
这是可用于测试https://github.com/StephaneDelcroix/mt-speed的示例.它包含一个过度简化的一阶运动引擎,3501实体和精灵.
这里有趣的类是KinematicSprite.该代码按原样在cocos2d(包含在Cocos2D.dll中)的修改版本上工作.通过注释掉新的Dirty函数,并取消注释NodeToParentTransform和旧的Dirty,可以使其在库存cocos2d和cocos2d绑定上起作用.根据Subclassing bound type in mono touch,它仅适用于设备.我在iPad mini上获得20至22.5 fps的帧率.
解决方法:
are we supposed to name that Xamarin.iOS now?
是的,现在是Xamarin.iOS :-)
Or is this a tax to pay when P/Invoking in MT ?
从托管和非托管代码过渡时,有很多事情要做.蹦床负责:编组参数和返回值,处理托管异常,处理本地异常…
另外,您可能会进行多次转换,例如新的Managed();调用native init *,后者会调用(native)setFoo:返回到(托管)Foo setter(并返回到调用者).
因此,即使每个部分都很快,但如果您不进行操作(或只是打个电话),仍然值得注意,因为用户没有太多时间可以分期偿还.
Is there a way to speed that up, from one side or the other (native or managed) ?
是.首先,请确保您测量真实的事物.例如.
>以上任务与模拟器和设备不同,例如JIT与AOT,x86和ARM具有不同的ABI;
>调试和发布构建配置还将使用不同的代码;
因此,您可能想评估iOS(ARM)设备上的Release版本.
接下来应该做的是确保“链接所有程序集”已启用(如果您具有非SDK绑定,例如Cocos2d).这不会改变蹦床,但是当您调用base时,您正在调用绑定代码.
事实证明,链接器在绑定方面非常聪明,可以删除您情况下不需要的代码.例如.
> remove checks and branches related to IsDirectBinding
;
> remove code related to NewRefCount
(sgen option);
> remove checks and branches related to ‘Runtime.Arch`;
> remove checks for UI thread checks(以防您继承自UIKit);和
>我们将来添加的任何将来的优化:-)
编辑:启用链接器的另一个原因是,它删除了绑定中多余的(未使用的)方法-减少了本机代码需要回调到托管世界的可能性(并且更少的转换意味着更快的时间)
其他方式更具侵入性,可能需要更改代码以最大程度地减少托管代码和本机代码之间的混乱.例如.有时你可以打电话
var x = new X (1, 2, 3, 4);
要么
var x = new X ();
x.a = 1;
x.b = 2;
x.c = 3;
x.d = 4;
您可以猜测第一种情况将需要较少的转换(并且速度更快).如果不存在这样的API,则可以添加它-但这应该是一个最少的选择(在其他地方,优化可能会为您带来更大的回报).
标签:performance,objective-c,xamarin-ios,c 来源: https://codeday.me/bug/20191031/1974184.html