Set asArray method

tim Rowledge tim at rowledge.org
Mon Oct 17 04:37:10 UTC 2005


On 16-Oct-05, at 9:16 PM, Ralph Boland wrote:
>
> I discovered that Set inherits the asArray method from Collection
> which is written
> as follows:
> "
>     | anArray index |
>     anArray := Array new: self size.
>     index := 0.
>     self associationsDo: [:each | anArray at: (index := index + 1)  
> put: each].
>     ^ anArray
> "
>
> Since Set does not have an 'associationsDo:' method  the corresponding
> method in Collection is used which just invokes the 'do:' method which
> is implemented
> in Set.

In most cases I suspect the cost ofallocating the anArray is going to  
be a substantial part of the time; you aren't reducing that at all.  
Sending #associationsDo: instead of #do: costs you a single message  
send.

> I felt that this was too inefficient so I implemented 'asArray' in Set
> as follows:
>
> "
>             | anArray newIndex |
>
>     anArray := Array new: self size.
>     newIndex := 1.
>     1 to: array size do:  [:index |
>                 | elem |
>             (elem := array at: index)
>         ifNotNil: [
>             anArray at: newIndex put: elem.
>             newIndex := newIndex + 1].
>         ].
>
>     ^ anArray
> "

By explicitly copying the code over you lose any chance of  
benefitting from a performance improvement that might someday be made  
in the #do: method. You 'lock in' that particular view of how it  
should be done. Sometimes it is a win, sometimes it isn't.

>
> This causes 'asArray' in class Dictionary to fail because it now
> inherits the asArray
> method from Set instead of Collection so I copied verbatum the  
> asArray method
> from Collection to Dictionary.  So far everything works.

By getting rid of the #associationsDo: you killed the value of the  
method for Dictionary.

> I have the following questions:
>
> 1)  For me the cost of the extra code was worth the gain in
> efficientcy (I believe;
>      I didn't actually do any measurements).
If you did no measuremnts, what do you base your belief on? These  
things are not always (often?) something that can be judged by  
inspection. Measurement under use conditions over a wide range of  
circumstances is crucial, absolutely crucial. Cue major rant on  
stupid benchmarks, dumb code, foolish users etc.

>      Given the importance of Sets and its subclasses (Like  
> Dictionary) is this
>      modification not worth being in Squeak itself?
>      Note that I find there are many places in Squeak where I would
> have reimplemented
>      a method rather then use inheritance so I am probably at  
> variance with the
>      Squeak community.  Even so, the above case seems to me to be
> especially bad.
>      Comments?

Inheriting code is usually the right answer in my experience, for the  
problems I have had to solve. It massively eases code management,  
comprehensibility, debugging and life in general. It makes the image  
smaller. It improves your sex life.

>
> 3)   An alternative to 2) would be if there was some way to control  
> from which
>       class a method is inherited.  Say, for example we could write  
> 'asArray' in
>       Dictionary as  "^super(Collection) asArray"  implying that the
> version of 'asArray'
>       in the super class of Dictionary called Collection is to be  
> used.
>       This seems to me to be a simple and efficient solution.
Agh! No, not that! Total destruction of inheritence, and creeping  
javanism!
Insert wise Yodaish homily about code copying leading to target class  
specifiying, leading to java  - and java leads to .net ! Sigh, young  
ones need much guidance.


tim
-- 
tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim





More information about the Squeak-dev mailing list