【问题标题】:Iterating through blocks vs fast enumeration vs for loop遍历块 vs 快速枚举 vs for 循环
【发布时间】:2014-04-22 18:21:43
【问题描述】:

我认为遍历 Blocks 比枚举更快,在某些情况下确实如此。但是,在这个简单的示例中,我有一个数据数组,并且我正在使用不同的迭代方法创建多个数组,结果不是我所期望的。

一个解释会很有帮助。

NSMutableArray *dataArray =[[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray1 = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray2 = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray3 = [[[NSMutableArray alloc] init] autorelease];

NSDate *dt1 = [NSDate date];
for (int j=0; j<10000000;j++)
{
    [dataArray addObject:[NSNumber numberWithInt:j]];
}

NSDate *dt2 = [NSDate date];
int cnt = [dataArray count];
//Using normal for loop
for (int k=0; k<cnt;k++)
{
    [mArray1 addObject:[dataArray objectAtIndex:k]];
}

//Using Fast Enumeration
NSDate *dt3 = [NSDate date];
for (NSNumber *num in dataArray)
{
    [mArray2 addObject:num];
}


//Enumerating using Blocks
NSDate *dt4 = [NSDate date];
[dataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    [mArray3 addObject:obj];
}];
NSDate *dt5 = [NSDate date];

NSLog(@"Time taken to create the data array %f",[dt2 timeIntervalSinceDate:dt1]);
NSLog(@"Time taken to iterate using normal for loop %f",[dt3 timeIntervalSinceDate:dt2]);
NSLog(@"Time taken to iterate using fast enumeration %f",[dt4 timeIntervalSinceDate:dt3]);
NSLog(@"Time taken to iterate using blocks %f",[dt5 timeIntervalSinceDate:dt4]);

//创建数据数组所花费的时间 0.383750

//使用普通for循环0.309719迭代所花费的时间

//使用快速枚举0.278467进行迭代所花费的时间

//使用块 0.526629 进行迭代所花费的时间

【问题讨论】:

  • 这里也报道了“快速枚举”比“块枚举”更快:blog.bignerdranch.com/2337-incremental-arrayification
  • 您是否运行了数百次测试以获得平均值?以不同的顺序运行它们怎么样?每个测试都会占用大量内存。
  • 如果你关心这个级别的性能,Objective-C 不是正确的语言。 IMO,它相当快。如果您需要更快的方法,您应该使用 C++。而且,顺便说一句。您的测量结果(相关)显示了预期结果。

标签: objective-c cocoa for-loop objective-c-blocks fast-enumeration


【解决方案1】:

关于所有不同的枚举器,post by NSHipster (@mattt) 非常好。阅读它,它将解释所有差异。

快速枚举速度更快,但块枚举的额外好处是拥有对象及其索引,这很有用!

【讨论】:

  • 从 NSHipster@matt 中提取。除非您在迭代时确实需要数字索引,否则使用 for/in NSFastEnumeration 循环几乎总是更快。
  • 是的,我没有这么说 :) 这完全取决于您的用例,如果您有一些项目并希望索引有用的话!
【解决方案2】:

就像 gimpycpu 所说,使用块的并发枚举是您将看到使用块枚举的性能影响的地方。利用 GCD 并枚举各种线程(在线程安全数据集上)可能是您所希望的。

示例枚举

图表/说明:Results

测试/代码示例:Code


如果并发是一个问题,请考虑尝试二分搜索以显着提升性能。

  • 需要一个排序的 NSArray。

【讨论】:

    【解决方案3】:

    我没有分析生成的程序集就可以看到的唯一原因如下。

    与其他循环方法相比,调用块有开销。

    您也可以尝试enumerateObjectsWithOptions:NSEnumerationConcurrent,实际上它可以比快速循环更快,因为它可以并行化。

    请记住,如果您在块内使用同步的东西,if 不会更快(不确定 NSArray 是否同步)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2012-10-02
      • 1970-01-01
      • 2011-03-24
      相关资源
      最近更新 更多