che*_*ica 4 c# objective-c xamarin.ios ipad ios
编辑:添加unsafe了C#代码的版本.谢谢你们这个建议,unsafeC#代码运行得更快,但只有3%左右.
简短版本:我在C#和Objective-C中编写了一些基准代码,并在iPad 3上进行了测试.MonoTouch/C#版本比Objective-C中的相同代码需要多50%-150%的执行时间.这是我的问题:我可以编写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,以在调试模式下运行,并27'162 ms在释放模式.unsafe需要116'885 ms在DEBUG模式和40'002 msRELEASE模式下运行.unsafe90'372 ms38'764 ms当然,RELEASE模式是我关心的.
鉴于MonoTouch编译为与LLVMObj-C 相同的本机代码,这种差异对我来说似乎有点高.
这是我使用的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;
Run Code Online (Sandbox Code Playgroud)
GetTimeMs64()用<sys/time.h>的gettimeofday.
这是我的C#/ MonoTouch代码,在unsafe版本中:
var array = new float[10000]; // 10'000
var watch = System.Diagnostics.Stopwatch.StartNew();
fixed (float* arr = array)
{
for (int j = 0; j < 100000; j++) // 100'000
{
*(arr + 0) = 0;
*(arr + 1) = 1;
for (int 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;
}
}
}
}
watch.Stop();
Run Code Online (Sandbox Code Playgroud)
编辑2:这是我们从Xamarin得到的答案:
该特定示例存在两个问题,其损害单声道性能.
首先,如果您使用的是默认的MonoTouch编译器,而不是LLVM,则可以预期性能会降低,因为它会针对编译速度而不是执行速度进行调整.LLVM将为您提供更好的结果.
其次,mono符合关于浮点的ECMA规范,并且所有计算都具有双精度.与使用浮点数的C代码相比,这通常具有可测量的性能成本.
我们一直在研究如何在不影响正确性的情况下放松双精度性能,或者至少采用选择机制.
就像Marc建议你应该使用unsafe代码一样,MonoTouch支持这个.NET功能.
这将删除.NET数组边界检查,这是一个不错的,更安全的.NET功能,但性能受到惩罚(因为必须检查每个数组访问).
这将使您的代码看起来更多(源代码和本机代码)看起来像Objective-C代码,性能应该更接近.我仍然建议你unsafe只在性能真正重要时使用代码(并且在测量增益值得之后).
| 归档时间: |
|
| 查看次数: |
658 次 |
| 最近记录: |