|
// |
|
// ProfileSharedKeySetTests.m |
|
// ProfileSharedKeySetTests |
|
// |
|
// Created by Marc Prud'hommeaux <[email protected]> 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 |