**The block approach** avoids running the lookup algorithm for *every key*:
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
NSLog(@"%@ => %@", key, value);
}];
Even though [`NSDictionary`][1] is implemented as a [hashtable][2] (which means that the cost of looking up an element is [`O(1)`][3]), lookups still slow down your iteration by *a constant factor*.
My measurements show that for a dictionary `d` of numbers ...
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
NSNumber* value = @(i);
dict[value.stringValue] = value;
}
... summing up the numbers with the block approach ...
__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
sum += value.intValue;
}];
... rather than the loop approach ...
int sum = 0;
for (NSString* key in dict)
sum += [dict[key] intValue];
... **is about 40% faster**.
**EDIT**: The new SDK (6.1+) appears to optimise loop iteration, so **the loop approach is now about 20% faster than the block approach**, at least for the simple case above.
[1]:
[To see links please register here]
[2]:
[To see links please register here]
[3]:
[To see links please register here]