提问人:Heat Miser 提问时间:8/29/2008 最后编辑:The Archetypal PaulHeat Miser 更新时间:6/9/2015 访问量:7057
Cocoa 中的 NSEnumerator 性能与 for 循环
NSEnumerator performance vs for loop in Cocoa
问:
我知道,如果您有一个修改循环中项计数的循环,那么在集合上使用 NSEnumerator 是确保您的代码爆炸的最佳方法,但是我想了解 NSEnumerator 类和老式 for 循环之间的性能权衡
答:
它们非常相似。在 Objective-C 2.0 中,大多数枚举现在默认为该枚举,该枚举会为集合中的每个对象创建一个地址缓冲区,然后它可以传递该缓冲区。在经典的 for 循环中保存的一个步骤是不必每次都在循环中调用。要枚举的集合的内部实现快速枚举,而无需调用 。NSFastEnumeration
objectAtIndex:i
objectAtIndex:i method
缓冲区是枚举时无法更改集合、对象地址将更改以及生成的缓冲区将不再匹配的部分原因。
作为奖励,2.0 中的格式看起来和经典的 for 循环一样好:
for ( Type newVariable in expression ) {
stmts
}
阅读以下文档以更深入地了解:NSFastEnumeration 协议参考
评论
NSFastEnumeration
在 Objective-C 2.0 中使用新语法通常是遍历集合的最快方法,因为它可以在堆栈上维护缓冲区并将成批的项放入其中。for (... in ...)
使用通常是最慢的方式,因为它经常复制正在迭代的集合;对于不可变集合,这可能很便宜(相当于 ),但对于可变集合,它可能会导致创建不可变副本。NSEnumerator
-retain
执行自己的迭代(例如,使用 )通常介于两者之间,因为虽然您不会有潜在的复制开销,但您也不会从基础集合中获取成批的对象。-[NSArray objectAtIndex:]
(PS - 这个问题应该标记为 Objective-C,而不是 C,因为这是一个 Cocoa 类,并且新语法特定于 Objective-C。NSEnumerator
for (... in ...)
运行几次测试后,结果几乎相同。每个测量块连续运行 10 次。
在我的情况下,结果从最快到最慢:
- 为。。in (testPerformanceExample3) (0.006秒)
- While (testPerformanceExample4) (0.026 秒)
- for(;;)(testPerformanceExample1)(0.027秒)
- 枚举块 (testPerformanceExample2) (0.067 秒)
for 和 while 循环几乎相同。
它包含从 0 到 999999 的 100 万个对象。tmp
NSArray
- (NSArray *)createArray
{
self.tmpArray = [NSMutableArray array];
for (int i = 0; i < 1000000; i++)
{
[self.tmpArray addObject:@(i)];
}
return self.tmpArray;
}
整个代码:
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) NSMutableArray *tmpArray;
- (NSArray *)createArray;
@end
ViewController.m的
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createArray];
}
- (NSArray *)createArray
{
self.tmpArray = [NSMutableArray array];
for (int i = 0; i < 1000000; i++)
{
[self.tmpArray addObject:@(i)];
}
return self.tmpArray;
}
@end
MyTestfile.m(我的测试文件.m)
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "ViewController.h"
@interface TestCaseXcodeTests : XCTestCase
{
ViewController *vc;
NSArray *tmp;
}
@end
@implementation TestCaseXcodeTests
- (void)setUp {
[super setUp];
vc = [[ViewController alloc] init];
tmp = vc.createArray;
}
- (void)testPerformanceExample1
{
[self measureBlock:^{
for (int i = 0; i < [tmp count]; i++)
{
[tmp objectAtIndex:i];
}
}];
}
- (void)testPerformanceExample2
{
[self measureBlock:^{
[tmp enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
obj;
}];
}];
}
- (void)testPerformanceExample3
{
[self measureBlock:^{
for (NSNumber *num in tmp)
{
num;
}
}];
}
- (void)testPerformanceExample4
{
[self measureBlock:^{
int i = 0;
while (i < [tmp count])
{
[tmp objectAtIndex:i];
i++;
}
}];
}
@end
有关更多信息,请访问:Apple的“关于使用Xcode进行测试”
评论
上一个:导出具有音频淡入和淡出的 QTMovie 的最佳方式
下一个:传递数据集
评论