iOS性能优化之NSDateFormatter

作者: 11e17ad00a2a | 来源:发表于2018-01-05 11:46 被阅读622次

    为什么要优化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

    相关文章

      网友评论

      • ZFJ_张福杰:如果经常用到可以放在工程单利中,AppDelegate收到内存警告直接释放单利里面部分对象
        11e17ad00a2a:@岁月轻狂_杰 @岁月轻狂_杰 没必要、现在是lazy load 单例,memery worning 时自动释放cache

      本文标题:iOS性能优化之NSDateFormatter

      本文链接:https://www.haomeiwen.com/subject/jbvjnxtx.html