Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is NSMutableString's -appendString: method an efficient way to build up a large string?

I'm planning on building up a potentially large string by iterating over a collection and generating chunks at a time. If I were to simply start with an NSMutableString and repeatedly append chunks to it, does that work reasonably efficiently or is it a Schlemiel the Painter situation? It seems plausible to me that NSMutableString is implemented in a way that avoids this, but I can't find any discussion of this in the official documentation and I'd like to be sure.

(Now that I'm writing this out, I realize that in this case I can build up an NSArray of strings and use -componentsJoinedByString: just as easily, but this would be good to know anyway.)

like image 483
zem Avatar asked Sep 16 '10 19:09

zem


2 Answers

The Schlemiel situation per se does not occur, since all internal NS/CFString representations use an explicit length, like all sane string implementations. (A somewhat modified version of the source of the basic CoreFoundation types from OS X 10.6.2 is available here.) The real question is about allocation overhead.

In the posted code, mutable strings’ buffers grow by 50 % at a time unless they’re very large (at least ULONG_MAX / 3UL), giving an O(log n) bound on reallocations for practical scenarios. Using the NSArray approach should result in a single allocation. On the other hand, if you build the string piecewise and release the pieces while you go, you might get less cache/VM thrashing.

So basically, the golden rule of optimization applies: if benchmarking shows a problem (on a large but realistic data set), try both.

like image 120
Jens Ayton Avatar answered Oct 17 '22 01:10

Jens Ayton


I prefer to use NSArray's componentsJoinedByString: method over appendString because it gives you finer control over what the string actually looks like with less effort.

like image 38
Jacob Relkin Avatar answered Oct 16 '22 23:10

Jacob Relkin