added #newWithConcatenationOfAll: for tune concatenation of
multiple strings.
--- a/SeqColl.st Sat Jun 19 12:12:31 1999 +0200
+++ b/SeqColl.st Wed Jun 23 13:57:10 1999 +0200
@@ -86,6 +86,88 @@
^ newCollection
!
+newWithConcatenationOfAll:aCollectionOfCollections
+ "this creates and returns a new collection consisting
+ of the concatenation of all elements of the argument.
+ I.e. it has the same effect as concatenating all elements
+ of the argument using #, ,but is implemented more efficiently,
+ by avoiding repeated garbage allocations.
+ This is an O runtime algorithm, in contrast to the #, loop, which is O*O"
+
+ |totalSize newColl idx|
+
+ totalSize := aCollectionOfCollections
+ inject:0
+ into:[:sumSoFar :el | sumSoFar + el size].
+ newColl := self new:totalSize.
+ idx := 1.
+ aCollectionOfCollections do:[:el |
+ |sz|
+
+ sz := el size.
+ newColl replaceFrom:idx to:(idx+sz-1) with:el startingAt:1.
+ idx := idx + sz
+ ].
+ ^ newColl
+
+ "
+ this method optimizes the following (common) operation:
+
+ |s|
+
+ s := ''.
+ #('hello' ' ' 'world' ' ' 'this is ' 'ST/X') do:[:e|
+ s := s , e.
+ ].
+ s
+
+ String
+ newWithConcatenationOfAll:#('hello' ' ' 'world' ' ' 'this is ' 'ST/X')
+
+ String
+ newWithConcatenationOfAll:#()
+
+ Array
+ newWithConcatenationOfAll:#( (1 2 3 4) (5 6 7 8) (9 10 11 12) )
+
+ timing:
+ -------
+ speed-break-even is at around 5 elements for strings;
+ for more elements, #newWithConcatenationOfAll: is much faster.
+
+ |arr1 arr2 arr3 t|
+
+ arr1 := #('hello' ' ' 'world' ' ' 'this is ' 'ST/X').
+ arr2 := Array new:1000 withAll:'hello'.
+ arr3 := Array new:10000 withAll:'hello'.
+
+ (Array with:arr1 with:arr2 with:arr3) with:#(10000 100 10) do:[:arr :cnt |
+ t := Time millisecondsToRun:[
+ cnt timesRepeat:[
+ String
+ newWithConcatenationOfAll:arr
+ ]
+ ].
+ Transcript showCR:(arr size printString , ' elements - time for #newWithConcatenationOfAll :' , (t/cnt) asFloat printString , 'mS').
+ Transcript endEntry.
+
+ t := Time millisecondsToRun:[
+ cnt timesRepeat:[
+ |s|
+
+ s := ''.
+ arr do:[:e|
+ s := s , e.
+ ].
+ s
+ ]
+ ].
+ Transcript showCR:(arr size printString , ' elements - time for loop over #, :' , (t/cnt) asFloat printString , 'mS').
+ Transcript endEntry.
+ ]
+ "
+!
+
withSize:size
"return a new collection of size.
For variable size collections, this is different from #new:,
@@ -4147,6 +4229,6 @@
!SequenceableCollection class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/SeqColl.st,v 1.104 1999-05-18 19:08:55 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/SeqColl.st,v 1.105 1999-06-23 11:57:10 cg Exp $'
! !
SequenceableCollection initialize!
--- a/SequenceableCollection.st Sat Jun 19 12:12:31 1999 +0200
+++ b/SequenceableCollection.st Wed Jun 23 13:57:10 1999 +0200
@@ -86,6 +86,88 @@
^ newCollection
!
+newWithConcatenationOfAll:aCollectionOfCollections
+ "this creates and returns a new collection consisting
+ of the concatenation of all elements of the argument.
+ I.e. it has the same effect as concatenating all elements
+ of the argument using #, ,but is implemented more efficiently,
+ by avoiding repeated garbage allocations.
+ This is an O runtime algorithm, in contrast to the #, loop, which is O*O"
+
+ |totalSize newColl idx|
+
+ totalSize := aCollectionOfCollections
+ inject:0
+ into:[:sumSoFar :el | sumSoFar + el size].
+ newColl := self new:totalSize.
+ idx := 1.
+ aCollectionOfCollections do:[:el |
+ |sz|
+
+ sz := el size.
+ newColl replaceFrom:idx to:(idx+sz-1) with:el startingAt:1.
+ idx := idx + sz
+ ].
+ ^ newColl
+
+ "
+ this method optimizes the following (common) operation:
+
+ |s|
+
+ s := ''.
+ #('hello' ' ' 'world' ' ' 'this is ' 'ST/X') do:[:e|
+ s := s , e.
+ ].
+ s
+
+ String
+ newWithConcatenationOfAll:#('hello' ' ' 'world' ' ' 'this is ' 'ST/X')
+
+ String
+ newWithConcatenationOfAll:#()
+
+ Array
+ newWithConcatenationOfAll:#( (1 2 3 4) (5 6 7 8) (9 10 11 12) )
+
+ timing:
+ -------
+ speed-break-even is at around 5 elements for strings;
+ for more elements, #newWithConcatenationOfAll: is much faster.
+
+ |arr1 arr2 arr3 t|
+
+ arr1 := #('hello' ' ' 'world' ' ' 'this is ' 'ST/X').
+ arr2 := Array new:1000 withAll:'hello'.
+ arr3 := Array new:10000 withAll:'hello'.
+
+ (Array with:arr1 with:arr2 with:arr3) with:#(10000 100 10) do:[:arr :cnt |
+ t := Time millisecondsToRun:[
+ cnt timesRepeat:[
+ String
+ newWithConcatenationOfAll:arr
+ ]
+ ].
+ Transcript showCR:(arr size printString , ' elements - time for #newWithConcatenationOfAll :' , (t/cnt) asFloat printString , 'mS').
+ Transcript endEntry.
+
+ t := Time millisecondsToRun:[
+ cnt timesRepeat:[
+ |s|
+
+ s := ''.
+ arr do:[:e|
+ s := s , e.
+ ].
+ s
+ ]
+ ].
+ Transcript showCR:(arr size printString , ' elements - time for loop over #, :' , (t/cnt) asFloat printString , 'mS').
+ Transcript endEntry.
+ ]
+ "
+!
+
withSize:size
"return a new collection of size.
For variable size collections, this is different from #new:,
@@ -4147,6 +4229,6 @@
!SequenceableCollection class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.104 1999-05-18 19:08:55 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/SequenceableCollection.st,v 1.105 1999-06-23 11:57:10 cg Exp $'
! !
SequenceableCollection initialize!