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
|