2KB项目,专业的源码交易网站 帮助 收藏 每日签到

NSArray 列举功能研讨

  • 时间:2019-03-14 09:40 编辑:2KB 来源:2KB.COM 阅读:398
  • 扫一扫,手机访问
  • 分享
摘要:
Objective-C 英文原文:NSArray enumeration performance examined

有一天,我在考虑 NSArray 列举办法 (也称迭代办法): Mac OS X 10.6 和 iOS 4 带来了以块(block)构成的漂亮新天下,enumerateObjectsUsingBlock: 办法随之而来。我觉得这个办法要慢于疾速列举 (for (object in array) { ... }),由于有整体开支,但我其实不能断定。因而我决议做一次功能测评。

都有哪些列举办法?

整体来讲,我们有4种可使用的列举办法 (参考 Mike Ash 的 周五常用问题 2010-04-09: Objective-C 的列举办法比照)。

  1. objectAtIndex: enumeration

    运用一个 for 轮回,递增轮回变量,然后用 [myArray objectAtIndex:index] 来拜访元素。这是最根本的列举方式。

    NSUInteger count = [myArray count];
    for (NSUInteger index = 0; index < count ; index++) {
        [self doSomethingWith:[myArray objectAtIndex:index]];
    }

  2. NSEnumerator

    内部迭代(external iteration)的方式: [myArray objectEnumerator] 前往一个工具,这个工具有  nextObject 办法。我们可以轮回挪用这个办法,直到前往 nil 为止。

    NSEnumerator *enumerator = [myArray objectEnumerator];
    id object;
    while (object = [enumerator nextObject]) {
        [self doSomethingWith:object];
    }

  3. NSFastEnumerator

    The idea behind 疾速列举 的思惟是应用 C 数组疾速拜访 来优化迭代。不只它实际上比传统的  NSEnumerator 更快,并且 Objective-C 2.0 供给了这类简明的语法:

    id object;
    for (object in myArray) {
        [self doSomethingWith:object];
    }

  4. Block enumeration(块列举)

    引入 blocks 后呈现的办法,它可以基于块来迭代拜访一个数组。它的语法没有疾速列举那末简练,但它有一个风趣的特征: 并发列举。假如列举的次序其实不主要,并且施行的处置可以并发实行,不必锁,这类办法可以在多核零碎上带来相当分明的效力晋升。概况参考 并发列举一节

    [myArray enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
        [self doSomethingWith:object];
    }];
    [myArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [self doSomethingWith:object];
    }];

线性列举

起首,我们会商一下线性列举:一个项目接着前一个。

图表

结论

有一点使人诧异的是,NSEnumerator乃至比运用objectAtIndex:还慢。这关于Mac OS X 和IOS是一个现实。我猜测这是因为列举器在每次迭代时都去反省数组能否被修正。天然地,疾速列举保管了每一个原始的名字,因而是最快的处理计划。

关于小的数组,block enumeration 比objectAtIndex:稍慢一点,但在有大量元素的数组里,它的功能变得与fast enumeration差未几快。

fast enumeration和NSEnumeration之间的差别在非常多地方曾经十分分明:关于iPhone 4S,前者破费约0.037秒然后者需求0.140秒。这曾经相差了3.7陪。

其它翻译版本 (1) 加载中

奇异的一点

初次在顺序平分配 NSArray 和初次用objectEnumerator 获得 enumerator 都需求异常长的工夫才干完成。例如,在我 2007 年的 17 寸 MacBook Pro 上分派含一个元素的数组,所需工夫的中位数是 415 纳秒。但初次分派的时分会需求 500,000 纳秒,有时乃至要到 1,000,000 纳秒!获得 enumerator 也是如斯:虽然中位数只要 673 纳秒,初次获得却要花 500,000 纳秒以上。

我只能猜想此中的缘由,但我疑心延迟加载是祸首罪魁。在实践使用中,你可能不会留意到这一点,由于比及履行你的代码时,Cocoa 或 Cocoa Touch 极可能曾经创立过数组了。

并发列举

假如状况答应,你可以选择用块列举来并发列举工具。这意味着盘算的任务量可以疏散到几个 CPU 内核上。并非每种列举过程当中的处置都是可并发的,因而只要没用到锁的时分,才干运用并发列举:要末每步操纵的确是绝对互相自力的,要末有原子性的操纵可用 (如 OSAtomicAdd32 之类)。

那末,它比拟其他列举类型有多大优势呢?

图表

结论

元素未几时,并发列举是今朝最慢的办法。首要缘由多是为了让数组能并发拜访而做的预备任务和开启线程(我不晓得用的是 GCD 仍是“传统的”线程,这不主要;这是我们不需关怀的完成细节)。

虽然如斯,假如数组足够大,并发列举忽然就成了最快的办法了,正如我们所料。在 iPhone 4S 上列举 100 万个元素,用并发列举需求 0.024 秒,但疾速列举需求 0.036 秒。相形之下,仍是统一个数组,NSEnumeration 要用 0.139 秒! 这曾经长短常大的差距了,足有 5.7 倍之多。

在我的办公室,2011 iMac 24"采取了酷睿i7四核CPU,同时在0.0016秒以内罗列了百万项。统一数组疾速列举了0.0044秒和NSEnumeration o.oo93秒。阿谁因数是5.8,它十分靠近于ipone 4S的后果。在这里,我等待一个更大的差别,固然,在我的2007 MacBook采取了Core2 Duo双核CPU,在这里因数恰好是3.7.当同时列举的阈值成为有效,在某处以我的测试是10,000和50,000份子之间。用更少的份子元素,去掉正常的块迭代。

其它翻译版本 (1) 加载中

分派方法

我也想晓得列举的功能会不会受数组创立方法的影响。我测试了两个分歧的办法:

  1. 起首创立一个 C 数组,外面援用了数组元素的工具实例,然后再用 initWithObjects:count: 创立NSArray。

  2. 间接创立 NSMutableArray 并顺次用 addObject: 添加工具。

后果是迭代进程的没有差别,但分派进程有所分歧:initWithObjects:count: 快一些。数组元素非常多时,差距愈加明显。这个例子创立了一个元素为 NSNumber 的数组:

NSArray *generateArrayMalloc(NSUInteger numEntries) {
    id *entries;
    NSArray *result;
        
    entries = malloc(sizeof(id) * numEntries);
    for (NSUInteger i = 0; i < numEntries; i++) {
        entries[i] = [NSNumber numberWithUnsignedInt:i];
    }
    
    result = [NSArray arrayWithObjects:entries count:numEntries];
    
    free(entries);
    return result;
}

我是怎么来丈量的?

你可以从 http://darkdust.net/files/arraytest.m 来下载这个测试使用 看看我是怎么来丈量的。根本上我就是丈量反复迭代一个数组(甚么处置也不做)1000次需求多长工夫。在图表中,取每一个数组尺寸的均匀值。这个使用的编译选项是封闭优化(-O0)。关于 iOS,我是在一个 iPhone 4S 长进行的测试。对 MAC OS X,我用我家里2007年产的 MacBook Pro 17”和我办公室2011年产的 iMac 24”来测试。MAC OS X的图表显示的是iMac上的后果,在MacBook Pro上的图表看起来与此类似,只是更慢一些。

本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协定,假如我们的任务有进犯到您的权益,请实时联络我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部