[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