关于EnumerateObjectsUsingBlock和for-in之间的较量

http://blog.csdn.net/scboyhj__/article/details/51397104

关于EnumerateObjectsUsingBlock和for-in之间的较量

如果我们要遍历一个数组, 上过编程课程的童鞋都会想到For语句去循环.

Objective C 提供一个Block的遍历方法, 那么用它还是用For好呢?

下面我们去实践一下:

遍历一个数组看谁快

参赛选手 ForLoopFor - inenumerateObjectsUsingBlock这个三个方法:

<code class="objectivec" style="padding:0px; font-family:Menlo,Monaco,Consolas,'Courier New',monospace; font-size:12px; border:none; background-color:transparent">    <span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> *test = [<span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> array];
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-keyword" style="color:#85990;">int</span> i = <span class="hljs-number" style="color:#2aa198;">0</span>; i < <span class="hljs-number" style="color:#2aa198;">1000000</span>; i ++) {
        [test addObject:@(i)];
    }

    __block <span class="hljs-keyword" style="color:#85990;">int</span> sum = <span class="hljs-number" style="color:#2aa198;">0</span>;
    <span class="hljs-keyword" style="color:#85990;">double</span> date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-keyword" style="color:#85990;">int</span> i = <span class="hljs-number" style="color:#2aa198;">0</span>; i < test<span class="hljs-variable" style="color:#b5890;">.count</span>; i ++) {
        sum += [test[i] integerValue];
    }
    <span class="hljs-keyword" style="color:#85990;">double</span> date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"Sum : %d ForLoop Time: %f ms"</span>,sum,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);


    sum = <span class="hljs-number" style="color:#2aa198;">0</span>;
    date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-built_in" style="color:#268bd2;">NSNumber</span> *num <span class="hljs-keyword" style="color:#85990;">in</span> test) {
        sum += [num integerValue];
    }
    date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"Sum : %d For-in Time: %f ms"</span>,sum,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);


    sum = <span class="hljs-number" style="color:#2aa198;">0</span>;
    date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    [test enumerateObjectsUsingBlock:^(<span class="hljs-keyword" style="color:#85990;">id</span> obj, <span class="hljs-built_in" style="color:#268bd2;">NSUInteger</span> idx, <span class="hljs-built_in" style="color:#268bd2;">BOOL</span> *stop) {
        sum += [obj integerValue];
    }];
    date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"Sum : %d enumrateBlock Time: %f ms"</span>,sum,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);</code>

最后输出如下:


打印输出
  • For-in方法最快速

    结论:

    当只是遍历一个数组的时候使用For-in会比较快速, 推荐使用For-in遍历数组.

通过Value查找Index看谁快

假如现在我们要查找一个Value, 这个Value 值是100001, 找出它的index (数组的序列号).

那么现在我们来比较一下
参赛选手 For - inenumerateObjectsUsingBlockenumerateObjectsWithOptions 这个三个方法: (ForLoop已经不再继续讨论了)

<code class="objectivec" style="padding:0px; font-family:Menlo,Monaco,Consolas,'Courier New',monospace; font-size:12px; border:none; background-color:transparent">    <span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> *test = [<span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> array];
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-keyword" style="color:#85990;">int</span> i = <span class="hljs-number" style="color:#2aa198;">0</span>; i < <span class="hljs-number" style="color:#2aa198;">10000000</span>; i ++) {
        [test addObject:@(i + <span class="hljs-number" style="color:#2aa198;">10</span>)];
    }

    <span class="hljs-comment" style="color:#93a1a1;">//For-in</span>
    __block <span class="hljs-built_in" style="color:#268bd2;">NSInteger</span> index = <span class="hljs-number" style="color:#2aa198;">0</span>;
    <span class="hljs-keyword" style="color:#85990;">double</span> date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-built_in" style="color:#268bd2;">NSNumber</span> *num <span class="hljs-keyword" style="color:#85990;">in</span> test) {
        <span class="hljs-keyword" style="color:#85990;">if</span> ([num integerValue] == <span class="hljs-number" style="color:#2aa198;">9999999</span>) {
            index = [test indexOfObject:num];
            <span class="hljs-keyword" style="color:#85990;">break</span>;
        }
    }
    <span class="hljs-keyword" style="color:#85990;">double</span> date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"index : %ld For-in Time: %f ms"</span>,(<span class="hljs-keyword" style="color:#85990;">long</span>)index,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);

    <span class="hljs-comment" style="color:#93a1a1;">//enumerateObjectsUsingBlock</span>
    index = <span class="hljs-number" style="color:#2aa198;">0</span>;
    date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    [test enumerateObjectsUsingBlock:^(<span class="hljs-keyword" style="color:#85990;">id</span> num, <span class="hljs-built_in" style="color:#268bd2;">NSUInteger</span> idx, <span class="hljs-built_in" style="color:#268bd2;">BOOL</span> *stop) {
        <span class="hljs-keyword" style="color:#85990;">if</span> ([num integerValue] == <span class="hljs-number" style="color:#2aa198;">9999999</span>) {
            index = idx;
            *stop = <span class="hljs-literal">YES</span>;
        }
    }];
    date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"index : %ld enumerateBlock Time: %f ms"</span>,(<span class="hljs-keyword" style="color:#85990;">long</span>)index,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);

    <span class="hljs-comment" style="color:#93a1a1;">//enumerateObjectsWithOptions</span>
    index = <span class="hljs-number" style="color:#2aa198;">0</span>;
    date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    [test enumerateObjectsWithOptions:<span class="hljs-built_in" style="color:#268bd2;">NSEnumerationConcurrent</span> usingBlock:^(<span class="hljs-keyword" style="color:#85990;">id</span> num, <span class="hljs-built_in" style="color:#268bd2;">NSUInteger</span> idx, <span class="hljs-built_in" style="color:#268bd2;">BOOL</span> *stop) {
        <span class="hljs-keyword" style="color:#85990;">if</span> ([num integerValue] == <span class="hljs-number" style="color:#2aa198;">9999999</span>) {
            index = idx;
            *stop = <span class="hljs-literal">YES</span>;
        }
    }];
    date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"index : %ld enumerateObjectsWithOptions Time: %f ms"</span>,(<span class="hljs-keyword" style="color:#85990;">long</span>)index,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);</code>

最后输出如下图:


打印输出
  • enumerateObjectsWithOptions方法最快速

    结论:

    通过Value查询index的时候, 面对大量的数组推荐使用 enumerateObjectsWithOptions的并行方法.
    For-inenumerateObjectsWithOptions方法这里我比较喜欢第二种写法简洁直观.

现在咱们要遍历字典

这里我们比较一下使用 For-in 和 enumerateKeysAndObjectsUsingBlock 这个两个方法:

<code class="objectivec" style="padding:0px; font-family:Menlo,Monaco,Consolas,'Courier New',monospace; font-size:12px; border:none; background-color:transparent">    <span class="hljs-built_in" style="color:#268bd2;">NSDictionary</span> *testDictionary = @{
                                     <span class="hljs-string" style="color:#2aa198;">@"Auther"</span> : <span class="hljs-string" style="color:#2aa198;">@"yyyyy"</span>,
                                     <span class="hljs-string" style="color:#2aa198;">@"Game"</span> : <span class="hljs-string" style="color:#2aa198;">@"Dota"</span>,
                                     <span class="hljs-string" style="color:#2aa198;">@"App"</span> : <span class="hljs-string" style="color:#2aa198;">@"dddddd"</span>,
                                     <span class="hljs-string" style="color:#2aa198;">@"Market"</span> : <span class="hljs-string" style="color:#2aa198;">@"AppStore"</span>
                                    };

    <span class="hljs-comment" style="color:#93a1a1;">//For - in</span>
    <span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> *forInArry = [<span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> array];
    <span class="hljs-keyword" style="color:#85990;">double</span> date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    <span class="hljs-built_in" style="color:#268bd2;">NSArray</span> *keys = [testDictionary  allKeys];
    <span class="hljs-keyword" style="color:#85990;">for</span> (<span class="hljs-built_in" style="color:#268bd2;">NSString</span> *key <span class="hljs-keyword" style="color:#85990;">in</span> keys) {
        <span class="hljs-built_in" style="color:#268bd2;">NSString</span> *Value = testDictionary[key];
        [forInArry addObject:Value];
    }
    <span class="hljs-keyword" style="color:#85990;">double</span> date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"index : %ld For-in Time: %f ms"</span>,(<span class="hljs-keyword" style="color:#85990;">long</span>)index,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);

    <span class="hljs-comment" style="color:#93a1a1;">//enumerateKeysAndObjectsUsingBlock</span>
    date_s = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>();
    <span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> *enumArry = [<span class="hljs-built_in" style="color:#268bd2;">NSMutableArray</span> array];
    [testDictionary enumerateKeysAndObjectsUsingBlock:^(<span class="hljs-keyword" style="color:#85990;">id</span> key, <span class="hljs-keyword" style="color:#85990;">id</span> obj, <span class="hljs-built_in" style="color:#268bd2;">BOOL</span> *stop) {
        [enumArry addObject:obj];
    }];
    date_current = <span class="hljs-built_in" style="color:#268bd2;">CFAbsoluteTimeGetCurrent</span>() - date_s;
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"index : %ld For-in Time: %f ms"</span>,(<span class="hljs-keyword" style="color:#85990;">long</span>)index,date_current * <span class="hljs-number" style="color:#2aa198;">1000</span>);

    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"ForInArr: %@"</span>,forInArry);
    <span class="hljs-built_in" style="color:#268bd2;">NSLog</span>(<span class="hljs-string" style="color:#2aa198;">@"enumArry: %@"</span>,enumArry);</code>

打印输出:


打印输出
  • enumerateKeysAndObjectsUsingBlock胜出

    结论:

    当我们想遍历字典类型的时候, 推荐使用enumerateKeysAndObjectsUsingBlock
    不仅仅是因为速度快, 更是因为代码更优雅和直观.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值