Gri*_*ess 1 collections objective-c
我有一个应用程序,每一步迭代一个数组,当数组为空时,我似乎得到惊人的缓慢结果.所以,我调查了一些类似的后续测试:
NSMutableArray* ar = [NSMutableArray array];
double time = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < 10000; i++)
{
for (NSObject* obj in ar)
{
[obj retain];
[obj release];
}
}
time = CFAbsoluteTimeGetCurrent() - time;
printf("Empty Time: %1.12f", time / 10000.0f);
time = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < 10000; i++)
{
if ([ar count] > 0)
{
for (NSObject* obj in ar)
{
[obj retain];
[obj release];
}
}
}
time = CFAbsoluteTimeGetCurrent() - time;
printf("Checked Time: %1.12f", time / 10000.0f);
Run Code Online (Sandbox Code Playgroud)
我尝试了100 | 1,000 | 10,000次迭代间隔,结果如下:
Empty Time: 0.000000039935 //100
Checked Time: 0.000000020266 //100
Empty Time: 0.000000018001 //1000
Checked Time: 0.000000011027 //1000
Empty Time: 0.000000015503 //10000
Checked Time: 0.000000008899 //10000
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这表明使用简单计数检查可以显着提高低迭代运行的性能(可能是因为缓存方案).这对我来说绝对令人惊讶,因为我期望Objective-C编译/运行时在执行foreach循环时已经进行了此检查!有没有人知道为什么会出现这种情况,如果有任何方法可以从这个循环设置中挤出更多的性能?谢谢!
空数组在典型的Cocoa程序中并不常见,也不会迭代数千次的空数组.
如果看到空数组的枚举在仪器中显示为CPU周期的重要消费者,那将是特别令人惊讶的.
鉴于Foundation和Core Foundation针对现实世界的性能模式进行了优化,因此不会进行0计数检查也就不足为奇了.
但是,如果你真的必须迭代一个空数组数十亿次,最快的方法是使用一个块:
time = CFAbsoluteTimeGetCurrent();
[ar enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[obj retain];
[obj release];
}];
Run Code Online (Sandbox Code Playgroud)
我将您的代码粘贴到Foundation工具的main()中,并在相对较新的MacBook Pro上获得:
Empty Time: 0.000000019896
Checked Time: 0.000000007498
Block Time: 0.000000000298
Run Code Online (Sandbox Code Playgroud)
当然,而不是空数组,只需使用nil.即我之后第二次做了所有的测试ar = nil;.
ar = nil;
time = CFAbsoluteTimeGetCurrent();
for (int i = 0; i < 10000; i++)
{
for (NSObject* obj in ar)
{
[obj retain];
[obj release];
}
}
... etc ...
Empty Time: 0.000000019902
Checked Time: 0.000000007999
Block Time: 0.000000000298
nil Empty Time: 0.000000015599
nil Checked Time: 0.000000004703
nil Block Time: 0.000000000000
Run Code Online (Sandbox Code Playgroud)
但总的来说,如果你的数据结构那么复杂,并且你在每个帧渲染上对它们进行了大量的反击,那么我建议可以按顺序使用不同的数据结构.
当然,只有你实际上使用了仪器来对代码进行采样并且正在优化占据整个CPU周期的很大一部分的东西.
| 归档时间: |
|
| 查看次数: |
821 次 |
| 最近记录: |