Skip to content

Instantly share code, notes, and snippets.

@marcprux
Created July 16, 2012 15:13
Show Gist options
  • Save marcprux/3123267 to your computer and use it in GitHub Desktop.
Save marcprux/3123267 to your computer and use it in GitHub Desktop.
Simple test case to profile any speed increases that might come out of using the new dictionaryWithSharedKeySet method of creating dictionaries
//
// ProfileSharedKeySetTests.m
// ProfileSharedKeySetTests
//
// Created by Marc Prud'hommeaux <mwp1@cornell.edu> on 7/16/12.
//
/**
Simple test case to profile any speed increases that might come out of using the new dictionaryWithSharedKeySet method of creating dictionaries.
For the record, on my machine (Macbook Pro Retina), I see an average speedup of 25% when using dictionaryWithSharedKeySet over normal NSMutableDictionary:
keyCount=5 iterations=5000 shared=0.04 nonshared=0.05 speedup=18.10%
keyCount=5 iterations=10000 shared=0.13 nonshared=0.15 speedup=20.20%
keyCount=5 iterations=15000 shared=0.24 nonshared=0.29 speedup=21.19%
keyCount=5 iterations=20000 shared=0.39 nonshared=0.46 speedup=17.74%
keyCount=25 iterations=5000 shared=0.52 nonshared=0.62 speedup=19.25%
keyCount=25 iterations=10000 shared=0.76 nonshared=0.95 speedup=24.25%
keyCount=25 iterations=15000 shared=1.13 nonshared=1.43 speedup=26.94%
keyCount=25 iterations=20000 shared=1.62 nonshared=2.06 speedup=27.49%
keyCount=625 iterations=5000 shared=4.70 nonshared=6.20 speedup=31.93%
keyCount=625 iterations=10000 shared=10.84 nonshared=14.28 speedup=31.75%
keyCount=625 iterations=15000 shared=20.02 nonshared=26.23 speedup=31.01%
keyCount=625 iterations=20000 shared=32.22 nonshared=42.41 speedup=31.63%
average of speedups: 25.12% count: 12 stddev: 5.44
*/
#import "ProfileSharedKeySetTests.h"
@implementation ProfileSharedKeySetTests
/** @brief get and set keyCount keys in a shared/non-shared keySet dictionary N times and return the number of seconds it took */
- (NSTimeInterval)testShared:(BOOL)shared count:(NSUInteger)keyCount iterations:(NSUInteger)iterations {
NSMutableArray *keys = [NSMutableArray arrayWithCapacity:keyCount];
for (NSUInteger i = 0; i < keyCount; i++) {
id randomKey = [[NSUUID UUID] UUIDString];
[keys addObject:randomKey];
}
NSParameterAssert(keys.count == keyCount);
id sharedKeys = shared ? [NSDictionary sharedKeySetForKeys:keys] : nil;
id value = @(1); // simple value
NSMutableDictionary *dict = sharedKeys ? [NSMutableDictionary dictionaryWithSharedKeySet:sharedKeys] : [NSMutableDictionary dictionaryWithCapacity:keyCount];
// naïve shuffle the key array to see whether re-ordering the keys changes the performance
[keys sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return arc4random() % 2 == 0 ? NSOrderedAscending : NSOrderedDescending;
}];
NSDate *start = [NSDate date];
for (NSUInteger i = 0; i < iterations; i++) {
for (NSUInteger k = 0; k < keyCount; k++) {
dict[keys[k]] = value; // set
}
for (NSUInteger k = 0; k < keyCount; k++) {
id value = dict[keys[k]]; // get
NSParameterAssert(value);
}
}
NSTimeInterval duration = -[start timeIntervalSinceNow];
return duration;
}
- (void)testExample {
NSMutableArray *speedups = [NSMutableArray array];
for (NSUInteger keyCount = 5; keyCount <= 625; keyCount *= keyCount) {
for (NSUInteger iterations = 5000; iterations <= 20000; iterations += 5000) {
NSTimeInterval sharedTime, nonsharedTime;
for (int i = 0; i < 5; i++) {
sharedTime += [self testShared:YES count:keyCount iterations:iterations];
nonsharedTime += [self testShared:NO count:keyCount iterations:iterations];
}
NSTimeInterval speedup = ((nonsharedTime - sharedTime) / sharedTime) * 100.;
[speedups addObject:@(speedup)];
NSLog(@"keyCount=%d iterations=%d shared=%.2f nonshared=%.2f speedup=%.2f%%", (int)keyCount, (int)iterations, (sharedTime), (nonsharedTime), speedup);
}
}
NSArray *sups = @[[NSExpression expressionForConstantValue:speedups]];
NSLog(@"average of speedups: %.2f%% count: %.0f stddev: %.2f",
[[[NSExpression expressionForFunction:@"average:" arguments:sups] expressionValueWithObject:nil context:nil] doubleValue],
[[[NSExpression expressionForFunction:@"count:" arguments:sups] expressionValueWithObject:nil context:nil] doubleValue],
[[[NSExpression expressionForFunction:@"stddev:" arguments:sups] expressionValueWithObject:nil context:nil] doubleValue]);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment