如何最大限度地降低分配和初始化NSDateFormatter的成本?

JJD*_*JJD 9 cocoa multithreading memory-management nsdateformatter microbenchmark

我注意到使用一个NSDateFormatter可能非常昂贵.我发现分配和初始化对象已经消耗了很多时间.
此外,似乎NSDateFormatter在多线程中使用会增加成本.在线程必须互相等待的情况下是否存在阻塞?

我创建了一个小测试应用程序来说明问题.请检查一下.

这种成本的原因是什么?如何改善使用?


17,12. - 更新我的观察结果:我不理解为什么线程处理时线程运行时间比串行运行时更长.仅在使用NSDateFormatter时才会出现时差.

bbu*_*bum 17

注意:您的示例程序非常微观基准,并且非常有效地最大限度地放大了日期格式化程序的成本.您比较即使什么也不做做的事情.因此,不管是什么,它会表现为一些时间.

这些测试非常有价值且极具误导性.微观基准测试通常仅在您拥有Teh Slow的真实案例时才有用.如果您要将此基准测试速度提高10倍(事实上,您可能会按照我的建议进行操作),但实际情况仅为应用程序中使用的总CPU时间的1%,最终结果不会是一个显着的速度提升 - 它几乎不会引人注目.

这样的费用是什么原因?

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMdd HH:mm:ss.SSS"];
Run Code Online (Sandbox Code Playgroud)

最有可能的是,成本与必须解析/验证日期格式字符串以及必须执行任何类型的特定于语言环境的goop相关联NSDateFormatter.Cocoa对本地化提供了非常全面的支持,但这种支持是以复杂性为代价的.

看看你是如何编写一个相当棒的示例程序,你可以启动你的应用程序在仪器和尝试各种CPU采样仪器,以了解什么是消耗CPU周期和仪器如何工作(如果你发现任何有趣的,更新你的问题! ).

在线程必须互相等待的情况下是否存在阻塞?

我很惊讶当你使用来自多个线程的单个格式化程序时,它不会简单地崩溃. NSDateFormatter没有具体提到它是线程安全的.因此,您必须假设它不是线程安全的.

如何改善使用方法?

不要创建这么多的日期格式化程序!

要么为了一批操作而保留一个,然后摆脱它,或者,如果你一直使用它们,在应用程序运行开始时创建一个并保持不变,直到格式发生变化.

对于线程,请保持每个线程一个,如果你真的必须(我敢打赌这是过度的 - 你的应用程序的架构是这样的,每批操作创建一个将是更明智的).


sha*_*naw 5

我喜欢使用GCD顺序队列来确保线程安全,方便,有效,高效.就像是:

dispatch_queue_t formatterQueue = dispatch_queue_create("formatter queue", NULL);
NSDateFormatter *dateFormatter;
// ...
- (NSDate *)dateFromString:(NSString *)string
{
    __block NSDate *date = nil;
    dispatch_sync(formatterQueue, ^{
        date = [dateFormatter dateFromString:string];
    });
    return date;
}
Run Code Online (Sandbox Code Playgroud)