When we use a custom object as NSDictionary's key, we need to make sure the custom object conforms to "NSCopying" protocol, implement "isEqual" and "hash". Otherwise, there would be something wrong. In this wonderful article: http://www.objc.io/issue-7/value-objects.html, it indicated that it may have very bad performance issue.
let’s have a look at what happens when we don’t have a hash function, and we try to use Person objects as keys in a dictionary:
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
NSDate* start = [NSDate date];
for (int i = 0; i < 50000; i++) {
NSString* name = randomString();
Person* p = [[Person alloc] initWithName:name birthDate:[NSDate date] numberOfKids:i++];
[dictionary setObject:@"value" forKey:p];
}
NSLog(@"%f", [[NSDate date] timeIntervalSinceDate:start]);
This takes 29 seconds on my machine. In comparison, when we implement a basic hash function, the same code runs in 0.4 seconds. These are not proper benchmarks, but do give a very good indication of why it’s important to implement a proper hash function.
I know it is wrong if we do not provide hash function for the custom object. But why it has so big performance problem? As I know, if we do not implement hash function, custom object will use pointer as its hash. pointer is unique, so it is perfect hash if only consider performance issue.
Then I tried similar code on NSMutableSet instead of NSMutableDictionary and get opposite result. Use default hash function will run faster, why?