196 lines
5.4 KiB
Objective-C
196 lines
5.4 KiB
Objective-C
#import "BenchmarkYapCache.h"
|
|
#import "YapCache.h"
|
|
#import "YapCacheCollectionKey.h"
|
|
|
|
#define LOOP_COUNT 25000
|
|
|
|
|
|
@implementation BenchmarkYapCache
|
|
|
|
static NSMutableArray *keys_kv;
|
|
static NSMutableArray *keys_ckv;
|
|
static NSMutableArray *keysOrder;
|
|
|
|
static NSMutableArray *cacheSizes;
|
|
|
|
+ (NSString *)randomLetters:(NSUInteger)length
|
|
{
|
|
NSString *alphabet = @"abcdefghijklmnopqrstuvwxyz";
|
|
NSUInteger alphabetLength = [alphabet length];
|
|
|
|
NSMutableString *result = [NSMutableString stringWithCapacity:length];
|
|
|
|
NSUInteger i;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
unichar c = [alphabet characterAtIndex:arc4random_uniform(alphabetLength)];
|
|
|
|
[result appendFormat:@"%C", c];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
+ (void)generateKeysWithCacheSize:(NSUInteger)cacheSize hitPercentage:(double)hitPercentage
|
|
{
|
|
keys_kv = nil;
|
|
keys_ckv = nil;
|
|
keysOrder = nil;
|
|
|
|
NSUInteger keysCount = (cacheSize / hitPercentage);
|
|
keys_kv = [NSMutableArray arrayWithCapacity:keysCount];
|
|
keys_ckv = [NSMutableArray arrayWithCapacity:keysCount];
|
|
|
|
for (NSUInteger i = 0; i < keysCount; i++)
|
|
{
|
|
NSString *key = [self randomLetters:24];
|
|
YapCacheCollectionKey *ckey = [[YapCacheCollectionKey alloc] initWithCollection:@"" key:key];
|
|
|
|
[keys_kv addObject:key];
|
|
[keys_ckv addObject:ckey];
|
|
}
|
|
|
|
NSUInteger loopCount = LOOP_COUNT;
|
|
keysOrder = [NSMutableArray arrayWithCapacity:loopCount];
|
|
|
|
for (NSUInteger i = 0; i < LOOP_COUNT; i++)
|
|
{
|
|
[keysOrder addObject:@(arc4random_uniform(keysCount))];
|
|
}
|
|
}
|
|
|
|
+ (void)runTest1:(NSUInteger)cacheSize
|
|
{
|
|
NSCache *cache = [[NSCache alloc] init];
|
|
cache.countLimit = cacheSize;
|
|
|
|
NSDate *start = [NSDate date];
|
|
|
|
for (NSNumber *number in keysOrder)
|
|
{
|
|
id cacheKey = [keys_ckv objectAtIndex:[number unsignedIntegerValue]];
|
|
|
|
[cache setObject:[NSNull null] forKey:cacheKey];
|
|
}
|
|
|
|
NSTimeInterval elapsed = [start timeIntervalSinceNow] * -1.0;
|
|
NSLog(@"%@: elapsed = %.6f (loop=%d, cache=%d)",
|
|
NSStringFromSelector(_cmd), elapsed, LOOP_COUNT, cacheSize);
|
|
}
|
|
|
|
+ (void)runTest2:(NSUInteger)cacheSize
|
|
{
|
|
Class keyClass = [NSString class];
|
|
|
|
YapThreadUnsafeCache *cache = [[YapThreadUnsafeCache alloc] initWithKeyClass:keyClass countLimit:cacheSize];
|
|
|
|
NSDate *start = [NSDate date];
|
|
|
|
for (NSNumber *number in keysOrder)
|
|
{
|
|
NSString *key = [keys_kv objectAtIndex:[number unsignedIntegerValue]];
|
|
|
|
[cache setObject:[NSNull null] forKey:key];
|
|
}
|
|
|
|
NSTimeInterval elapsed = [start timeIntervalSinceNow] * -1.0;
|
|
NSLog(@"%@: elapsed = %.6f (loop=%d, cache=%d)",
|
|
NSStringFromSelector(_cmd), elapsed, LOOP_COUNT, cacheSize);
|
|
}
|
|
|
|
+ (void)runTests
|
|
{
|
|
if ([cacheSizes count] == 0) return;
|
|
|
|
NSUInteger cacheSize = [[cacheSizes objectAtIndex:0] unsignedIntegerValue];
|
|
[cacheSizes removeObjectAtIndex:0];
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
NSLog(@" \n\n\n ");
|
|
NSLog(@"====================================================");
|
|
NSLog(@"CACHE SIZE: %lu, HIT PERCENTAGE: 5%% \n\n", (unsigned long)cacheSize);
|
|
|
|
[self generateKeysWithCacheSize:cacheSize hitPercentage:0.05];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
NSLog(@"====================================================");
|
|
});
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
NSLog(@"CACHE SIZE: %lu, HIT PERCENTAGE: 25%% \n\n", (unsigned long)cacheSize);
|
|
|
|
[self generateKeysWithCacheSize:cacheSize hitPercentage:0.25];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
NSLog(@"====================================================");
|
|
});
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
NSLog(@"CACHE SIZE: %lu, HIT PERCENTAGE: 50%% \n\n", (unsigned long)cacheSize);
|
|
|
|
[self generateKeysWithCacheSize:cacheSize hitPercentage:0.5];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
NSLog(@"====================================================");
|
|
});
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
NSLog(@"CACHE SIZE: %lu, HIT PERCENTAGE: 75%% \n\n", (unsigned long)cacheSize);
|
|
|
|
[self generateKeysWithCacheSize:cacheSize hitPercentage:0.75];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
NSLog(@"====================================================");
|
|
});
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
NSLog(@"CACHE SIZE: %lu, HIT PERCENTAGE: 95%% \n\n", (unsigned long)cacheSize);
|
|
|
|
[self generateKeysWithCacheSize:cacheSize hitPercentage:0.95];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
[self runTest1:cacheSize];
|
|
[self runTest2:cacheSize];
|
|
NSLog(@"====================================================");
|
|
});
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
// Run the next test (with a different cacheSize)
|
|
[self runTests];
|
|
});
|
|
}
|
|
|
|
+ (void)startTests
|
|
{
|
|
cacheSizes = [@[ @(40), @(100), @(500), @(1000) ] mutableCopy];
|
|
|
|
double delayInSeconds = 0.1;
|
|
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
|
|
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
|
|
|
[self runTests];
|
|
});
|
|
}
|
|
|
|
@end
|