iOS性能优化之NSDateFormatter

为什么要优化NSDateFormatter?

首先,过度的创建NSDateFormatter用于NSDate与NSString之间转换,会导致App卡顿,打开Profile工具查一下性能,你会发现这种操作占CPU比例是非常高的。据官方说法,创建NSDateFormatter代价是比较高的,如果你使用的非常频繁,那么建议你缓存起来,缓存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
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html

解决方案: Cache in Memory

BTNSDateFormatterFactory 利用 NSCache, 以 stringFormatter+NSLocale的localeIdentifier 形成的string 为key缓存NSDateFormatter, 不用担心内存管理, 当内存警告时候, 会自动释放NSCache缓存的对象.

测试

- (void)testExample {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
    
    [self convertDateToStringUsingNewDateFormatter];
    [self convertDateToStringUsingBTNSDateFormatterFactoryFormatter];
    [self convertDateToStringUsingCLocaltime];
}

#define ITERATIONS (1024*10)
static double then, now;

#pragma test for costs time
- (void)convertDateToStringUsingNewDateFormatter
{
    then = CFAbsoluteTimeGetCurrent();
    for (NSUInteger i = 0; i < ITERATIONS; i++) {
        NSDateFormatter *newDateForMatter = [[NSDateFormatter alloc] init];
        [newDateForMatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
        [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)convertDateToStringUsingBTNSDateFormatterFactoryFormatter
{
    then = CFAbsoluteTimeGetCurrent();
    for (NSUInteger i = 0; i < ITERATIONS; i++) {
        NSDateFormatter *dateFormatterFactoryFormatter = [[BTNSDateFormatterFactory sharedFactory] dateFormatterWithFormat:@"yyyy-MM-dd" andLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
        self.dateAsString = [dateFormatterFactoryFormatter stringFromDate:[NSDate date]];
    }
    now = CFAbsoluteTimeGetCurrent();
    NSLog(@"Convert date to string using BTNSDateFormatterFactory Formatter 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);
}

测试结果

测试结果对比

使用方式

pod 'BTNSDateFormatterFactory'

github 有任何问题,欢迎issues、pr

你可能感兴趣的:(iOS性能优化之NSDateFormatter)