This article is published in the original "self-built blog", cnblogs synchronous publication, the format is not adjusted, the content of the original blog as the subject of my preface
The traversal of the collection is one of the most common operations in development, from the C-language classic for loop to the advantage of multi-core CPU traversal, the development of iOS has a number of sets of traversal methods, this article through the study and test to compare the efficiency of each operation method and the advantages of the potential, and summed up a few using the set traversal tips.
Common methods of traversal in iOS
The purpose of the traversal is to get an object in the collection or to perform an operation, so that the method that satisfies the condition can be an alternative:
- Classic for Loop
- For in (nsfastenumeration), if unfamiliar can refer to "Nshipster Introduction nsfastenumeration article"
- Makeobjectsperformselector
- KVC Set operator
- Enumerateobjectsusingblock
- Enumerateobjectswithoptions (nsenumerationconcurrent)
- Dispatch_apply
Conditions of experimental experiment
The test classes are as follows:
1234 |
@interface Sark NSObject @property (nonatomicnsinteger number;-(void//Sleep (0.01)@end |
The experiment is evaluated from two aspects:
- Use Nsarray with 100 objects and 1 million objects respectively, take only objects, do not perform operations, test traverse speed
doSomethingSlowTest Multi-task run speed in traversal using Nsarray traversal execution method with 100 objects
The experiment uses CFAbsoluteTimeGetCurrent() a record timestamp to calculate the elapsed time, in seconds.
Running on Iphone5 Real machine (Dual core CPU)
Experimental data
100 Object Traversal operations:
1234567 |
Classic for 0.001355-in0.0023080.001120KVC set operator (@sum . Number 0.004272 0.001145 0.001605 0.001380 |
1000000 Object Traversal Operations:
1234567 |
Classic for 1.246721-in0.0259550.068234KVC set operator (@sum . Number 21.677246 0.586034 0.722548 0.607100 |
100 object Traversal performs a time-consuming operation:
1234567 |
Classic for 1.106567-in1.1026431.103965KVC set operator (@sum . Number 1.104888 0.554670 0.554858 |
It is worth noting that
- The traversal speed is very fast for a lot of objects in the collection,
for in (NSFastEnumeration) but small traversal is not obvious (not yet normal for loop fast)
kvc集合运算符when using a large collection of operations, the efficiency is significantly reduced (1 million of the array outrageous 21 seconds more), while consuming a lot of memory and CPU
enumerateObjectsWithOptions(NSEnumerationConcurrent)And dispatch_apply(Concurrent) the traversal execution can take advantage of the multi-core CPU (experiment in the efficiency of the dual-core CPU basically x2)
Traverse Practice Tips Reverse Traversal
NSArrayand NSOrderedSet both support reverseObjectEnumerator the use of reverse traversal, such as:
1234 |
Nsarray *strings = @[@ "1"@ "2"@ "3"]; for (NSString *string in [strings Reverseobjectenumerator]) { NSLog (@ "%@"string);} |
This method is called only for the first time in the loop, so there is no need to worry about loops for each calculation.
At the same time, it enumerateObjectsWithOptions:NSEnumerationReverse is possible to use reverse traversal:
123 |
*sark *stop) { [Sark dosomething];}]; |
Use block to traverse the dictionary at the same time Key,value
The block version of the dictionary traversal can take both key and value (Forin can only take the key and then manually fetch value), such as:
1234 |
nsdictionary *dict = @{@"A": @ "1", @ "B": @"2"}; [Dict enumeratekeysandobjectsusingblock:^ (ID-IDBOOL *stop) { NSLog(@"key:%@, Value:%@", key, obj);}]; |
For time-consuming and sequence-independent traversal, use concurrent versions
123 |
*sark *stop) { [Sark Dosomethingslow];}]; |
Traversing the execution block is allocated on a multicore CPU (which is probably the GCD concurrent queue), which is worthwhile for time-consuming tasks, and benefits from not having to change the code after the CPU is upgraded to more cores. At the same time, the outside of the traversal is kept synchronized (after the traversal is complete before proceeding to the next line), guess the interior is probably gcd dispatch_group or semaphore control.
The tradeoff between code readability and efficiency
Although the above test results show that within the set element is not long, the classic for loop efficiency is higher than the Forin, but from the code readability, it is far less than forin look smoother, the same is the KVC set of operators, some built-in operations to keypath declare the way, Compared to the use of the For loop implementation, a line of code can be done, clear, but also eliminate the duplication of work, in the framework of the addition of the block support for the collection traversal, for the need to index traversal no longer need the classic for loop notation.
References
http://nshipster.com/enumerators/
Http://iosdevelopertips.com/objective-c/fast-enumeration-on-the-iphone.html
Original articles, reproduced please specify the source address, blog.sunnyxx.com