[Newbies] [Q] How should one concatenate Strings?
Bert Freudenberg
bert at impara.de
Wed May 10 07:42:15 UTC 2006
Am 09.05.2006 um 20:59 schrieb Damien Cassou:
>> If you are building very long strings by using , in an inner loop, it
>> can be slow because you will have an N squared algorithm. You can
>> convert that into a linear time algorithm by writing to an
>> WriteStream
>> using nextPut: and nextPutAll: and then asking the WriteStream for
>> its
>> contents. It leads to a little more complicated code, but on some
>> programs in can create a dramatic performance improvement. In
>> general, though, use "comma", since it is simpler.
>
> You should avoid optimizing your code before making sure it needs
> an improvement. Nevertheless, here is a simple benchmark for the
> two techniques:
>
> [| temp |
> temp := String new.
> (1 to: 100000)
> do: [:i | temp := temp, i asString]] timeToRun
>
> Answers 75.202 milliseconds
>
>
> [| temp |
> temp := WriteStream on: String new.
> (1 to: 100000)
> do: [:i | temp nextPutAll: i asString]] timeToRun
>
> Answers 3.169 milliseconds
>
> To get the string back from the Stream, use #contents:
>
> myWriteStream contents
Since using a stream to construct a collection is a very common task,
there is a nice helper construct for this:
String streamContents: [:stream |
1 to: 10000 do: [:i | stream print: i]]
This spares you to declare one temporary variable and is overall more
readable.
Also, I used the stream's #print: method which will append a string
representation of its argument - you could, of course, use
#nextPutAll:, too.
Btw, do *not* put parens around "1 to: 10000". Of course this works,
but writing "1 to: 10000 do:" uses the #to:do: message which is way
more efficient, and a tiny bit shorter to read, too.
- Bert -
More information about the Beginners
mailing list