本文介紹NSDateFormatter的性能瓶頸履羞,以及如何解決性能問題。
分別用NSDateFormatter和C的localtime()方法去將時間轉化成一個可讀的字符串庞溜。轉化1024*10次破讨,然后對比時間。
注:localtime()有不可重入和線程安全的問題尔苦,可用localtime_r替換涩馆。
- (void)viewDidLoad {
[super viewDidLoad];
[self convertDateToStringUsingNewDateFormatter];
[self convertDateToStringUsingCLocaltime];
}
- (void)convertDateToStringUsingNewDateFormatter
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
NSDateFormatter *newDateForMatter = [[NSDateFormatter alloc] init];
[newDateForMatter setTimeZone:self.timeZone];
[newDateForMatter setDateFormat:@"yyyy-MM-dd"];
self.dateAsString = [newDateForMatter stringFromDate:[NSDate date]];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using NSDateFormatter costs time: %f seconds!\n", now - then);
}
- (void)convertDateToStringUsingCLocaltime
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
time_t timeInterval = [NSDate date].timeIntervalSince1970;
struct tm *cTime = localtime(&timeInterval);
self.dateAsString = [NSString stringWithFormat:@"%d-%02d-%02d", cTime->tm_year + 1900, cTime->tm_mon + 1, cTime->tm_mday];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using C localtime costs time: %f seconds!\n", now - then);
}
在控制臺可以看到輸出結果:
NSDateFormatterEfficiency[34122:1583307] Convert date to string using NSDateFormatter costs time: 4.289286 seconds!
NSDateFormatterEfficiency[34122:1583307] Convert date to string using C localtime() costs time: 0.038355 seconds!
使用NSDateFormatter耗時4.289286秒,
使用localtime耗時0.038355秒允坚。
也就是說魂那,NSDateFormatter要比localtime慢100倍+!
用instruments跑了一下time profile稠项,
可以看到這性能差距之大涯雅。
為啥NSDateFormatter這么耗時呢?
蘋果官方文檔中寫到:
“Creating a date formatter is not a cheap operation. If you are likely to use a formatter frequently, it is typically more efficient to cache a single instance than to create and dispose of multiple instances. One approach is to use a static
variable.”
也就是說展运,創(chuàng)建NSDateFormatter的過程開銷很大活逆!建議使用時保持一個單例,而不是每次去重新創(chuàng)建
NSDateFormatter對象拗胜。
demo中加入一個單例NSDateFormatter的實現(xiàn)方法蔗候,
- (void)convertDateToStringUsingSingletonFormatter
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
self.dateAsString = [self.dateFormatter stringFromDate:[NSDate date]];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using Singleton Formatter costs time: %f seconds!\n", now - then);
}
控制臺輸出,
NSDateFormatterEfficiency[34122:1583307] Convert date to string using NSDateFormatter costs time: 4.231905 seconds!
NSDateFormatterEfficiency[34122:1583307] Convert date to string using Singleton Formatter costs time: 0.031584 seconds!
NSDateFormatterEfficiency[34050:1580882] Convert date to string using C localtime() costs time: 0.039877 seconds!
嗯挤土,若使用單例琴庵,NSDateFormatter開銷和localtime()的開銷差不多,甚至會稍快一些仰美。
綜上迷殿,最佳實踐應該是,在工程中添加一個NSDateFormatter的單例對象供全工程使用咖杂,需要注意的是庆寺,NSDateFormatter在iOS7之后(包括iOS7)才是線程安全的。