Simple String Question.

Richard A. O'Keefe ok at
Fri May 17 00:47:53 UTC 2002

goran.hultgren at wrote:
    [Using Time millisecondsToRun: [...], he found that #, is competitive
     with #streamContents: for small numbers of strings.]

Inspired by that, I thought I'd compare my
with #, and #streamContents:.
The results were disappointing.  A small change greatly improved the
results, but the nature of the change was disappointing to a lover of
Smalltalk's iteration methods.

As posted,
    Time millisecondsToRun: [
        10000 timesRepeat: [#('abc' 'def' 'ghi' 'jkl') concatenation]]
=> 1121 1128 1103 1146 1098
on a 250MHz Mac G3.  Changing this to
    Time millisecondsToRun: [
        10000 timesRepeat: [
	    #('abc' 'def' 'ghi' 'jkl') concatenationAs: String]]
shaves off a method call, for a 1.12 speedup.  Then replacing
    length := self inject: 0 into: [:sum :each | sum + each size]
    length := 0.
    self do: [:each | length := length + each size].
gives another 1.25 speedup, for a combined speedup of 1.4.

This leaves #concatenationAs: 1.08 times slower than #, for concatenating
four small strings.

I was disappointed that using #inject:into: made such a difference to the

A more interesting set of times shows what happens when you do a LOT
of concatenations:

    ss := (1 to: 3000) collect: [:each | each asString].
    Time millisecondsToRun: [
	r := ''.
	ss do: [:each | r := r , each]]
=>  809

    Time millisecondsToRun: [
	String streamContents: [:s |
	    ss do: [:each | s nextPutAll: each]]]
=>  26

    Time millisecondsToRun: [
	ss concatenationAs: String]
=>  21

The current version of #concatenationAs: is the best I can come up with,
short of making it a primitive.  To my mind, what this shows is that
the stream version is DARNED good, and it works for just as many cases
as #concatenationAs:.

More information about the Squeak-dev mailing list