On 17 Nov 2013, at 12:49, Andres Valloud <avall...@smalltalk.comcastbiz.net> wrote:
> Well, maybe, although it's interesting to consider how many strings streams > need to beat string concatenation. Moreover, streams aren't hyper efficient > either… Yes, indeed. It also depends on what is being concatenated (constants vs objects). Quick and dirty (totally unscientific): [ 'foo', 'bar' ] bench. '4,650,000 per second.' [ '' join: #( 'foo' 'bar' ) ] bench. '814,000 per second.' [ String streamContents: [ :out | out nextPutAll: 'foo'; nextPutAll: 'bar' ] ] bench. '1,900,000 per second.' [ 'foo', 'bar', 'baz' ] bench. '2,470,000 per second.' [ '' join: #( 'foo' 'bar' 'baz' ) ] bench. '719,000 per second.' [ String streamContents: [ :out | out nextPutAll: 'foo'; nextPutAll: 'bar'; nextPutAll: 'baz' ] ] bench. '1,710,000 per second.' [ 'foo', 'bar', 'baz', 'foobar' ] bench. '2,030,000 per second.' [ '' join: #( 'foo' 'bar' 'baz' 'foobar' ) ] bench. '665,000 per second.' [ String streamContents: [ :out | out nextPutAll: 'foo'; nextPutAll: 'bar'; nextPutAll: 'baz'; nextPutAll: 'foobar' ] ] bench. '1,580,000 per second.' [ Date today asString, $- asString, Time now asString ] bench. '61,800 per second.' [ String streamContents: [ :out | out print: Date today; nextPut: $-; print: Time now ] ] bench. '71,700 per second.' We’re only measuring execution speed, not memory allocation, which is important too. The length of the strings is a variable as well, of course. Furthermore, many #printOn: implementations are not very efficient while they should be. Conclusion, let’s be careful with a too simple advice. Sven > On 11/16/13 10:09 , b...@openinworld.com wrote: >> >> Code Critic rule Optimization > String concatenation instead of streams >> says: >> >> "Check for string concatenation inside some iteration message. Since >> string concatenation is O(n^2), it is better to use streaming since it >> is O(n) - assuming that n is large enough. As a general principal avoid >> , since the receiver is copied. Therefore chaining , messages will lead >> to multiple useless copies of the receiver." >> >> That is, >> String streamContents: [:s | >> #('abc' 'def' 'ghi') do: [:each | s nextPutAll: each asString]] >> >> should be used instead of... >> 'abc' , 'def' , 'ghi'. >> >> However the first clutters the code. What about something like... >> { 'abc' . 'def' . 'ghi' } asStreamString >> where >> Collection>>asStreamString >> ^ String streamContents: [:s | self do: [:each | s nextPutAll: >> each asString]] >> >> cheers -ben >> >