Oc/object-c/ios which kind of traverse nsarray/nsdictionary way fast? Test report

Source: Internet
Author: User
Tags allkeys

When you do the app, you always have to iterate through the array or dictionary multiple times.
What kind of traversal method is faster? I did the following tests:
First define the test macros:?
123456789 #define MULogTimeintervalBegin(INFO) NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];\NSTimeIntervalduration = 0;\NSLog(@"MULogTimeintervalBegin:%@", INFO)#define MULogTimeintervalPauseAndLog(INFO) duration = [NSDate timeIntervalSinceReferenceDate] - start;\start += duration;\NSLog(@"%@:%f", INFO, duration);\duration = 0#define TESTSCALE 100000


Then write the test code:
Nsarray:?
123456789101112131415161718192021222324252627282930 - (void)testArray{    NSMutableArray* testArray = [NSMutableArrayarrayWithCapacity:TESTSCALE];    for(NSIntegeri = 1; i <= TESTSCALE; ++i) {        [testArray addObject:[NSStringstringWithFormat:@"%ld", i]];    }    NSLog(@"init:%ld", [testArray count]);        __blockNSMutableString* sum = [NSMutableStringstringWithCapacity:TESTSCALE];        MULogTimeintervalBegin(@"ArrayTest");    NSUIntegercount = [testArray count];    for(NSIntegeri = 0; i < count; ++i) {        [sum appendString:[testArray objectAtIndex:i]];    }    [sum setString:@""];    MULogTimeintervalPauseAndLog(@"for statement");        for(NSString* item in testArray) {        [sum appendString:item];    }    [sum setString:@""];    MULogTimeintervalPauseAndLog(@"for-in");        [testArray enumerateObjectsUsingBlock:^(idobj, NSUIntegeridx, BOOL*stop) {        [sum appendString:obj];    }];    [sum setString:@""];    MULogTimeintervalPauseAndLog(@"enumerateBlock");}

Nsdictionary:?
123456789101112131415161718192021222324252627 - (void)testDictionary {    NSMutableDictionary* testDic = [NSMutableDictionarydictionaryWithCapacity:TESTSCALE];    for(NSIntegeri = 1; i <= TESTSCALE; ++i) {        [testDic setObject:@"test"forKey:[NSStringstringWithFormat:@"%ld", i]];    }    NSLog(@"init:%ld", [testDic count]);        __blockNSMutableString* sum = [NSMutableStringstringWithCapacity:TESTSCALE];        MULogTimeintervalBegin(@"DictionaryTest");    for(NSString* object in [testDic allValues]) {        [sum appendString:object];    }    [sum setString:@""];    MULogTimeintervalPauseAndLog(@"for statement allValues");        for(idakey in [testDic allKeys]) {        [sum appendString:[testDic objectForKey:akey]];    }    [sum setString:@""];    MULogTimeintervalPauseAndLog(@"for statement allKeys");        [testDic enumerateKeysAndObjectsUsingBlock:^(idkey, idobj, BOOL*stop) {        [sum appendString:obj];    } ];    MULogTimeintervalPauseAndLog(@"enumeration");}


Here are the test results:
Test case '-[looptesttests Testarray] ' started.
2012-08-02 17:14:22.061 otest[388:303] init:100000
2012-08-02 17:14:22.062 otest[388:303] Mulogtimeintervalbegin:arraytest
2012-08-02 17:14:22.075 otest[388:303]for statement:0.013108
2012-08-02 17:14:22.083 otest[388:303]for-in:0.008186
2012-08-02 17:14:22.095 otest[388:303] enumerateblock:0.012290
Test case '-[looptesttests Testarray] ' passed (0.165 seconds).
Test case '-[looptesttests testdictionary] ' started.
2012-08-02 17:14:22.273 otest[388:303] init:100000
2012-08-02 17:14:22.274 otest[388:303] Mulogtimeintervalbegin:dictionarytest
2012-08-02 17:14:22.284 otest[388:303] for statement allvalues:0.010566
2012-08-02 17:14:22.307 otest[388:303] for statement allkeys:0.022377
2012-08-02 17:14:22.330 otest[388:303] enumeration:0.023914
Test case '-[looptesttests testdictionary] ' passed (0.217 seconds).

It can be seen that for arrays, the for-in way is the fastest, the normal style for and block mode speed is similar. For dictionaries, the Allvalues way is the fastest, AllKeys and block are similar.
So, why is this so?
Nsarray:?
123 for(NSIntegeri = 0; i < count; ++i) {        [sum appendString:[testArray objectAtIndex:i]];}

This is due to the existence of: [OBJECTATINDEX:I] Such a fetch operation, so the speed will be reduced.
and?
123 for(NSString* item in testArray) {        [sum appendString:item];}

Although there is a take action, it is faster to bypass the message mechanism of OC. It is also possible that the compiler was optimized for for-in.
Why is block slower? This remains to be studied.
Nsdictionary:?
123 for(idakey in [testDic allKeys]) {        [sum appendString:[testDic objectForKey:akey]];}

This is obvious, the second method is more Objectforkey operation. Block's words need to be studied.
Google a bit, StackOverflow above has a similar discussion: Click to open the link
The main idea is that the for-in syntax will create a buffer for the memory address of the element inside the container, and it is more efficient to take the address of the element directly from the buffer, rather than by invoking the method. In addition, this is one of the reasons why container elements cannot be modified in the loop body.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.