2010-09-16 48 views
4

我正在计划通过迭代集合并一次生成块来构建一个潜在的大字符串。如果我只是简单地从一个NSMutableString开始,并反复追加块,那么这是否合理有效地工作,或者它是一个Schlemiel the Painter的情况?对我来说似乎合理的是,NSMutableString的实现方式可以避免这种情况,但在官方文档中我找不到任何关于此的讨论,我想确定。NSMutableString的-appendString:方法是构建大型字符串的有效方法吗?

(现在,我写这篇文章的时候,我意识到,在这种情况下,我可以建立串的一个NSArray并使用-componentsJoinedByString:很容易,但是这将是很好反正就知道了)

回答

6

Schlemiel情况本身并不会发生,因为所有内部NS/CFString表示都使用明确的长度,就像所有理智的字符串实现一样。 (OS X 10.6.2的基本CoreFoundation类型的来源的某种修改版本可用于here。)真正的问题是关于分配开销。

在发布的代码中,可变字符串的缓冲区每次增长50%,除非它们非常大(至少为ULONG_MAX/3UL),在实际场景的重新分配上给出O(log n)限制。使用NSArray方法应该导致单个分配。另一方面,如果您在分离时构建字符串并释放这些字符串,则可能会减少缓存/ VM抖动。

所以基本上,优化的黄金法则适用于:如果基准测试显示问题(在一个大而实际的数据集上),请同时尝试两种方法。

+1

正是我在找的,谢谢。 – zem 2010-09-16 21:27:06

+0

+1,真棒。 O(n^2)复制性能不会发生,因为分配的内存呈指数增长,因此分摊的复制成本为O(n)。 – orip 2013-01-07 10:04:58

2

我倾向于使用NSArraycomponentsJoinedByString:方法而不是appendString,因为它可以更好地控制字符串实际看起来像什么而不费力。

+0

是的,我意识到,但它会很高兴知道是否应该使用appendString。 – zem 2010-09-16 19:45:38

+0

'-componentsJoinedByString:'是一个'NSArray'方法。 – 2010-09-16 19:52:10

+0

@Alexsander,是的,我知道。 – 2010-09-16 19:53:52

0

我更经常使用NSString-stringByAppendingString:-stringByAppendingFormat:方法。有时是+stringWithFormat:方法。

+1

这并没有真正回答这个问题,因为'stringByAppending'Anything:将会或不像'append'一样具有相同的问题:无论是或不是。 'stringWithFormat:'肯定会*有问题,因为它必须将前缀和后缀都复制到结果字符串中。 – 2010-09-16 19:55:12

+0

我认为这些与NSMutableString的版本具有相同的性能。它没有回答我的问题,这是否比braindead old-school以null结尾的c样式字符串连接更有效。 – zem 2010-09-16 19:55:41

0

这是一个实现细节。如果它是用C字符串实现的,那么它会有一个Schlemiel Painter问题,因为Schlemiel需要查找空终止符来知道从哪里开始做更多的绘画。如果以任何方式声明长度,那么就不存在这样的问题,因为施莱米尔知道他需要多长时间撑杆跳到弦的末端才能做更多的绘画。最终,你不可能知道这一点(没有反汇编),也不能依赖于在更新中保持不变的答案,所以你只需要有一定的信心,苹果框架工程师知道他们是什么,重新做。

最好等到你的应用程序中的某些东西不像应该的那样快,然后再对你的应用程序进行配置以查明它是什么。根据我的经验,这个框架几乎不会变慢。

+0

这就是我所担心的。我觉得这是应该披露的那种实现细节(或者至少是渐近的复杂性)。对于这种情况,我只会使用componentsJoinedByString(它直观地应该针对大量字符串进行优化),并接受这个答案,除非有人带着一些秘密知识进行弹出。 – zem 2010-09-16 20:06:56

0

通常我会在构建较小的字符串时使用appendString:,或者对其进行相对较少的修改。如果我建立一个大字符串,当然取决于当前的大小,也许从字符串项目填充的NSArray中创建字符串可能是有意义的。

一般来说,我不会使用appendString:来建立大的字符串。

0

我有一个情况,我不得不对NSMutableString appendString做很多调用,而且我可以告诉你一个事实,它比仅仅执行NSString的stringByAppendingString慢得多。只是FYI。

相关问题