Created
September 11, 2013 15:19
-
-
Save milch/6525132 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NSDate+FastParse.h" | |
#import <Foundation/Foundation.h> | |
#import "sqlite3.h" | |
typedef int64_t timestamp; | |
NSUInteger randomNumberInRange(NSUInteger start, NSUInteger end); | |
// Create a sample date using the ISO-8601 format. | |
// 2013-04-23T16:29:05Z | |
NSString* generateSampleDate(); | |
// Create an array of <count> dates in the ISO-8601 format. | |
NSArray* generateSampleDates(NSUInteger count); | |
// Parse all given dates using SQLite's strftime function | |
NSArray * parseDatesUsingSQLite(NSArray *dates); | |
// Parse all given dates using NSDateFormatter | |
NSArray * parseDatesUsingNSDateFormatter(NSArray *dates); | |
// Parse all given dates using strptime_l | |
NSArray * parseDatesUsingStrptime(NSArray *dates); | |
NSArray * parseDatesUsingFastParse(NSArray *dates); | |
static NSDateFormatter *dateFormatter = nil; | |
int main() | |
{ | |
@autoreleasepool { | |
const NSUInteger count = 1000000; | |
NSArray *dates = generateSampleDates(count); | |
NSDate *start = nil; | |
NSDate *end = nil; | |
start = [NSDate date]; | |
NSArray *dateFormatterArray = parseDatesUsingNSDateFormatter(dates); | |
end = [NSDate date]; | |
printf("NSDateFormatter took %4.3f seconds\n", [end timeIntervalSinceDate:start]); | |
start = [NSDate date]; | |
NSArray *strptimeArray = parseDatesUsingStrptime(dates); | |
end = [NSDate date]; | |
printf("strptime took %4.3f seconds\n", [end timeIntervalSinceDate:start]); | |
start = [NSDate date]; | |
NSArray *sqliteArray = parseDatesUsingSQLite(dates); | |
end = [NSDate date]; | |
printf("sqlite3 took %4.3f seconds\n", [end timeIntervalSinceDate:start]); | |
start = [NSDate date]; | |
NSArray *fastParseArray = parseDatesUsingFastParse(dates); | |
end = [NSDate date]; | |
printf("fastparse took %4.3f seconds\n", [end timeIntervalSinceDate:start]); | |
} | |
return 0; | |
} | |
NSArray* generateSampleDates(NSUInteger count) { | |
NSMutableArray *dates = [NSMutableArray array]; | |
for (int i = 0; i < count; i++) { | |
[dates addObject:generateSampleDate()]; | |
} | |
return dates; | |
} | |
NSString* generateSampleDate() { | |
NSUInteger year = randomNumberInRange(1980, 2013); | |
NSUInteger month = randomNumberInRange(1, 12); | |
NSUInteger date = randomNumberInRange(1, 28); | |
NSUInteger hour = randomNumberInRange(0, 23); | |
NSUInteger minute = randomNumberInRange(0, 59); | |
NSUInteger second = randomNumberInRange(0, 59); | |
NSString *dateString = [NSString stringWithFormat:@"%lu-%02lu-%02luT%02lu:%02lu:%02luZ", | |
year, | |
month, | |
date, | |
hour, | |
minute, | |
second | |
]; | |
return dateString; | |
} | |
NSArray * parseDatesUsingSQLite(NSArray *dates) { | |
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dates.count]; | |
sqlite3 *db = NULL; | |
sqlite3_open(":memory:", &db); | |
sqlite3_stmt *statement = NULL; | |
sqlite3_prepare_v2(db, "SELECT strftime('%s', ?);", -1, &statement, NULL); | |
for (NSString *dateString in dates) { | |
sqlite3_bind_text(statement, 1, [dateString UTF8String], -1, SQLITE_STATIC); | |
sqlite3_step(statement); | |
timestamp value = sqlite3_column_int64(statement, 0); | |
NSDate *date = [NSDate dateWithTimeIntervalSince1970:value]; | |
[array addObject:date]; | |
sqlite3_clear_bindings(statement); | |
sqlite3_reset(statement); | |
} | |
return array; | |
} | |
NSArray * parseDatesUsingNSDateFormatter(NSArray *dates) { | |
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dates.count]; | |
if (dateFormatter == nil) { | |
dateFormatter = [[NSDateFormatter alloc] init]; | |
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; | |
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; | |
} | |
for (NSString *dateString in dates) { | |
NSDate *date = [dateFormatter dateFromString:dateString]; | |
[array addObject:date]; | |
} | |
return array; | |
} | |
NSArray * parseDatesUsingStrptime(NSArray *dates) { | |
struct tm sometime; | |
const char *formatString = "%Y-%m-%dT%H:%M:%SZ"; | |
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dates.count]; | |
for (NSString *date in dates) { | |
strptime_l([date UTF8String], formatString, &sometime, NULL); | |
NSDate *date = [NSDate dateWithTimeIntervalSince1970: mktime(&sometime)]; | |
[array addObject:date]; | |
} | |
return array; | |
} | |
NSArray * parseDatesUsingFastParse(NSArray *dates) { | |
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dates.count]; | |
for (NSString *dateString in dates) { | |
NSDate *date = [NSDate dateFromString:dateString]; | |
[array addObject:date]; | |
} | |
return array; | |
} | |
NSUInteger randomNumberInRange(NSUInteger start, NSUInteger end) { | |
NSUInteger span = end - start; | |
return start + arc4random_uniform(span); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment