Simple String Question.

goran.hultgren at bluefish.se goran.hultgren at bluefish.se
Thu May 16 08:56:53 UTC 2002


Bijan Parsia <bparsia at email.unc.edu> wrote:
[SNIP]
> Important tip: concat is usually more expensive in Squeak than, say, in
> Python. Or rather, concat is not the preferred way to efficiently build
> large strings. E.g.,
> 
> 	'adfafds', 'adfdfa', 'adfa', 'adfasf'
> 
> will involve a fair bit of copying. A better way is to use a stream, and
> here's one of my favorite idioms for it:
> 
> 	String streamContents: [:strm | strm nextPutAll: 'adasfdaf';
> 					     nextPutAll: 'dafdak';...]
> 
> Disadvantage here is that you can still get a fair bit of copying, as the
> stream starts with a small collection and then doubles it at appropriate
> moments. To further tune you can do something like
> 
> 	WriteStream on: (String new: 1000).
> 
> Which will preallocate in the stream a collection of (at least closer
> to) the right size for a reasonably sized string.

In fact, two concatenations of small Strings seem to be more efficient
using #, but after that Streams seem to win out (Note: I haven't really
looked why, this is just observation), try Alt-p on the following
expressions (my timings included after arrow):

Time millisecondsToRun: [10000 timesRepeat: ['abc', 'def', 'ghi',
'jkl']]     -> 276 284 295 263 268

Time millisecondsToRun: [10000 timesRepeat: [String streamContents: [:s
| s nextPutAll: 'abc'; nextPutAll:'def'; nextPutAll: 'ghi'; nextPutAll:
'jkl']]]  -> 260 265 271 285 279

Actually a draw! :-) But if we change it and remove one concat...

Time millisecondsToRun: [10000 timesRepeat: ['abc', 'def', 'ghi']] ->
179 164 160 159 176 

Time millisecondsToRun: [10000 timesRepeat: [String streamContents: [:s
| s nextPutAll: 'abc'; nextPutAll:'def'; nextPutAll: 'ghi']]] -> 224 223
223 220 218

...the #, seems to win. So Streams don't seem to always be faster! :-)

> Cheers,
> Bijan Parsia.

Cheers, Göran



More information about the Squeak-dev mailing list