编辑:添加了unsafe
版本的C#代码。谢谢你们这个建议,unsafe
C#代码运行得更快,但只有3%左右。
简短版本:我在C#和Objective-C中编写了一些基准代码,并在iPad 3上进行了测试.MonoTouch / C#版本需要比执行时间多50%-150% Objective-C中的相同代码。这是我的问题:我能编写的C#代码执行速度比我用于基准测试的代码(见下文)要快,还是由一些固有的MonoTouch / Obj-C差异引起的?
长版:我刚刚为计划好的多平台游戏编写了一个小型原型。在将游戏核心从Windows / .NET移植到iPad 3 / MonoTouch之后,我注意到代码在iPad上运行的速度有多慢。游戏核心的某些关键部分在iPad CPU上比在英特尔CPU上慢了约10倍(这似乎是正常的,因为iPad使用ARM处理器运行)。
然而,由于这是我们游戏的一个主要问题,我在iPad 3上进行了一次小型基准测试,一次使用 MonoTouch ,然后用简单的 Objective-C进行同样的操作即可。基准测试执行了许多简单的float
添加和float
数组查找。由于MonoTouch是GC,我希望看到Obj-C有一点不同,但令我惊讶的是,MonoTouch代码比Obj-C代码需要更多的时间来运行。确切地说:
47'647 ms
才能在DEBUG模式下运行,27'162 ms
需要在RELEASE模式下运行。unsafe
指针的 MonoTouch 代码需要116'885 ms
在DEBUG模式下运行,40'002 ms
在RELEASE模式下运行。unsafe
指针需要90'372 ms
在DEBUG模式下运行,38'764 ms
在RELEASE模式下运行。< / LI>
当然,RELEASE模式是我关心的。
鉴于MonoTouch编译为与Obj-C相同的本地LLVM
代码,这种差异对我来说似乎有点高。
这是我使用的Obj-C代码:
int i, j;
long time = GetTimeMs64();
float * arr = (float *) malloc(10000 * sizeof(float)); // 10'000
for (j = 0; j < 100000; j++) { // 100'000
arr[0] = 0;
arr[1] = 1;
for (i = 2; i < 10000; i++) { // 10'000
arr[i] = arr[i - 2] + arr[i - 1];
if (arr[i] > 2000000000) { // prevent arithm. overflow
arr[i - 1] = 0;
arr[i] = 1;
}
}
}
long time2 = GetTimeMs64() - time;
GetTimeMs64()
使用<sys/time.h>
的{{1}}。
这是我的C#/ MonoTouch代码,gettimeofday
版本:
unsafe
编辑2:这是我们从Xamarin得到的答案:
此特定示例有两个问题会影响单声道 性能
首先,如果您使用的是默认的MonoTouch编译器,而不是LLVM, 你可以期待更低的性能,因为它已经调整了编译速度 而不是执行速度。 LLVM将为您提供更好的结果。
其次,单声道符合关于浮点和的ECMA规范 以双精度进行所有计算。这通常有一个 与使用C代码相比,特别是可衡量的性能成本 浮动。
我们一直在研究放松双精度性能的方法 没有妥协正确性,或者至少有选择权 机构。
答案 0 :(得分:5)
与Marc建议你应该使用unsafe
代码一样,MonoTouch支持这个.NET功能。
这将删除一个漂亮,更安全的.NET 功能的.NET数组边界检查,但会有性能损失(因为必须检查每个阵列访问 )。
这将使您的代码看起来更多(源代码和本机代码)看起来像Objective-C代码,性能应该更接近。我仍建议您仅在性能真正重要时使用unsafe
代码(并且在衡量增益值得之后)。