added #newWithConcatenationOfAll: for tune concatenation of
authorClaus Gittinger <cg@exept.de>
Wed, 23 Jun 1999 13:57:10 +0200
changeset 4303 4a2e5a5cb83d
parent 4302 b16969865f9f
child 4304 968d8b70d805
added #newWithConcatenationOfAll: for tune concatenation of multiple strings.
SeqColl.st
SequenceableCollection.st
--- 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!