Skip to content

Instantly share code, notes, and snippets.

@milch
Created September 11, 2013 15:19
Show Gist options
  • Save milch/6525132 to your computer and use it in GitHub Desktop.
Save milch/6525132 to your computer and use it in GitHub Desktop.
#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