[Pharo-project] Preallocation behavior

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Apr 28 13:01:07 CEST 2011


IMHO, you would need a stream equivalent of atAll:put: maybe something like
   stream next: 900 put: $A.

It would write directly to destination and save a copy versus say
   stream nextPutAll: (String new: 900 withAll: $A)

2011/4/28 Toon Verwaest <toon.verwaest at gmail.com>:
> On 04/28/2011 08:35 AM, jannik.laval wrote:
>
> First of all, I spy this source code:
> ====
> MessageTally spyOn:
>      [ 500 timesRepeat: [
>                      | str |
>                      str := ''.
>                      9000 timesRepeat: [ str := str, 'A' ]]].
> ====
>
> This is what Joel Spolsky called a "Shlemiel the Painter's algorithm"
> http://www.joelonsoftware.com/articles/fog0000000319.html
>
> It's obviously very slow and it's very different from the code below for
> obvious reasons.
>
> Other /languages that won't be named/ just do hacks to allow you to think in
> terms of string concatenation while it's optimized internally using buffers.
> This works well to make programs by dummies faster, but it also dumbs down
> programmers since you forget that stuff actually needs to be done.
>
> The result appears after 24 961 ms.
> An optimization is to use a Stream. Here is my source code:
> ===
> MessageTally spyOn:
>      [ 500 timesRepeat: [
>                      | str |
>                      str := WriteStream on: (String new).
>                      9000 timesRepeat: [ str nextPut: $A ]]].
> ===
> The result appears after 812 ms, which is a large improvement.
> Now, we could optimize again using the preallocation. Here is my source
> code:
> ====
> MessageTally spyOn:
>     [ 500 timesRepeat: [
>                     | str |
>                     str := WriteStream on: (String new: 10000).
>                     9000 timesRepeat: [ str nextPutAll: 'A' ]]].
> ====
> And the result is strange: it makes 2 times slower to display the result.
> The result appears after 1656 ms.
> Here is the spy result:
> ===
>  - 1656 tallies, 1656 msec.
> **Tree**
> --------------------------------
> Process: (40s)  464519168: nil
> --------------------------------
> **Leaves**
> 22.9% {380ms} UndefinedObject>>DoIt
> 22.5% {373ms} SmallInteger(Integer)>>timesRepeat:
> 22.2% {368ms} WriteStream>>nextPutAll:
> ===
> There is the call of UndefinedObject>>DoIt which is added and takes time.
> Does anyone know what is done during the preallocation ?
> Why is it slower than non-preallocation ?
> Thanks for your answers.
> Jannik
>



More information about the Pharo-project mailing list