collection enumeration

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

collection enumeration

cedreek
Hi all -

not an important question here, more a discussion. I was wondering
which method is the more appropriate (nice and/or efficient) to
enumerate all the elements of a collection and the index of each
elements...


(a) ---- à la C

(1 to: collection size) do: [:index |
                                                html render: 'Victime ', index printString.
                                                html render:
collection at: index]

(b) --- indexOf

collection do: [:victim |
                                                html render: 'Victime ', (collection indexOf: victim) printString.
                                                html render: victim]

(c) ---- keysAndValuesDo:

collection keysAndValuesDo: [:index :victim |
                                                html render: index printString.
                                                html render: member]

(d) ---- using a local var

| index |
index := 0.
collection do: [:victim | index := index + 1.
                                                html render: 'Victime ', index printString.
                                                html render: victim]

What solution would you suggest ?
I think we forget (a) and (d)
I like (c) but maybe (b) is more readable ?

Maybe there is another way ?

Thanks

Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Bert Freudenberg-3


Am 23.08.2006 um 21:15 schrieb cdrick:

> Hi all -
>
> not an important question here, more a discussion. I was wondering
> which method is the more appropriate (nice and/or efficient) to
> enumerate all the elements of a collection and the index of each
> elements...
>
>
> (a) ---- à la C
>
> (1 to: collection size) do: [:index |
> html render: 'Victime ', index printString.
>                                                html render:
> collection at: index]
>
> (b) --- indexOf
>
> collection do: [:victim |
> html render: 'Victime ', (collection indexOf: victim)  
> printString.
>                                                html render: victim]
>
> (c) ---- keysAndValuesDo:
>
> collection keysAndValuesDo: [:index :victim |
> html render: index printString.
>                                                html render: member]
>
> (d) ---- using a local var
>
> | index |
> index := 0.
> collection do: [:victim | index := index + 1.
> html render: 'Victime ', index printString.
>                                                html render: victim]
>
> What solution would you suggest ?
> I think we forget (a) and (d)
> I like (c) but maybe (b) is more readable ?
>
> Maybe there is another way ?

(c), though I like #withIndexDo: better since it mimics the #with:do:  
pattern.

- Bert -

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

cedreek
> >
> > Maybe there is another way ?
>
> (c), though I like #withIndexDo: better since it mimics the #with:do:
> pattern.
>

Cool.. I didn't ask for nothing ;)

Thanks Bert
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Damien Cassou-3
In reply to this post by Bert Freudenberg-3
Bert Freudenberg wrote:

>
>
> Am 23.08.2006 um 21:15 schrieb cdrick:
>
>> Hi all -
>>
>> not an important question here, more a discussion. I was wondering
>> which method is the more appropriate (nice and/or efficient) to
>> enumerate all the elements of a collection and the index of each
>> elements...
>>
>>
>> (a) ---- à la C
>>
>> (1 to: collection size) do: [:index |
>>                         html render: 'Victime ', index printString.
>>                                                html render:
>> collection at: index]
>>
>> (b) --- indexOf
>>
>> collection do: [:victim |
>>                         html render: 'Victime ', (collection indexOf:
>> victim) printString.
>>                                                html render: victim]
>>
>> (c) ---- keysAndValuesDo:
>>
>> collection keysAndValuesDo: [:index :victim |
>>                         html render: index printString.
>>                                                html render: member]
>>
>> (d) ---- using a local var
>>
>> | index |
>> index := 0.
>> collection do: [:victim | index := index + 1.
>>                         html render: 'Victime ', index printString.
>>                                                html render: victim]
>>
>> What solution would you suggest ?
>> I think we forget (a) and (d)
>> I like (c) but maybe (b) is more readable ?
>>
>> Maybe there is another way ?
>
> (c), though I like #withIndexDo: better since it mimics the #with:do:
> pattern.

I would vote for #withIndexDo: too which has in 'intention revealing
name' :-)

And, please forget about (b), this is way too slow and wrong.

Slow because the complexity jump from O(n) to O(n²). Remember that
#indexOf: has to search for the element in all the collection.

Wrong because:

collection := #($a $b $a).
collection
   do: [:each | Transcript
                  show: (collection indexOf: each);
                  space]

Will print '1 2 1' instead of '1 2 3'. Index answered by #indexOf: if
the first index on which the object is found.


Bye
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

stéphane ducasse-2
In reply to this post by Bert Freudenberg-3
but is a not the fastest one?
because you nearly only call primitives?

I did not check.
Cedric did you benchmark a and c.
even if large dictionaries degenerate in Squeak.

>> (a) ---- à la C
>>
>> (1 to: collection size) do: [:index |
>> html render: 'Victime ', index printString.
>>                                                html render:
>> collection at: index]
>>
>> (b) --- indexOf
>>
>> collection do: [:victim |
>> html render: 'Victime ', (collection indexOf: victim)  
>> printString.
>>                                                html render: victim]
>>
>> (c) ---- keysAndValuesDo:
>>
>> collection keysAndValuesDo: [:index :victim |
>> html render: index printString.
>>                                                html render: member]
>>
>> (d) ---- using a local var
>>
>> | index |
>> index := 0.
>> collection do: [:victim | index := index + 1.
>> html render: 'Victime ', index printString.
>>                                                html render: victim]
>>
>> What solution would you suggest ?
>> I think we forget (a) and (d)
>> I like (c) but maybe (b) is more readable ?
>>
>> Maybe there is another way ?
>
> (c), though I like #withIndexDo: better since it mimics the  
> #with:do: pattern.
>
> - Bert -
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Bert Freudenberg-3
(a) is certainly much slower if collection is a LinkedList

- Bert -

Am 23.08.2006 um 22:20 schrieb stéphane ducasse:

> but is a not the fastest one?
> because you nearly only call primitives?
>
> I did not check.
> Cedric did you benchmark a and c.
> even if large dictionaries degenerate in Squeak.
>
>>> (a) ---- à la C
>>>
>>> (1 to: collection size) do: [:index |
>>> html render: 'Victime ', index printString.
>>>                                                html render:
>>> collection at: index]
>>>
>>> (b) --- indexOf
>>>
>>> collection do: [:victim |
>>> html render: 'Victime ', (collection indexOf: victim)  
>>> printString.
>>>                                                html render: victim]
>>>
>>> (c) ---- keysAndValuesDo:
>>>
>>> collection keysAndValuesDo: [:index :victim |
>>> html render: index printString.
>>>                                                html render: member]
>>>
>>> (d) ---- using a local var
>>>
>>> | index |
>>> index := 0.
>>> collection do: [:victim | index := index + 1.
>>> html render: 'Victime ', index printString.
>>>                                                html render: victim]
>>>
>>> What solution would you suggest ?
>>> I think we forget (a) and (d)
>>> I like (c) but maybe (b) is more readable ?
>>>
>>> Maybe there is another way ?
>>
>> (c), though I like #withIndexDo: better since it mimics the  
>> #with:do: pattern.
>>
>> - Bert -

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Ralph Johnson
In reply to this post by cedreek
I usually use option C.

> (a) ---- à la C
>
> (1 to: collection size) do: [:index |
>                                                 html render: 'Victime ', index printString.
>                                                 html render: collection at: index]

This can be fast if collection is an array and if you say "1 to:
collection do: [:index | ..."
instead of creating an interval.  The compiler cheats for to:do: on a
SmallInteger and doesn't create the block.  But I would only use this
if the profiler showed it was a real improvement.  Almost always I
would use option C.

-Ralph
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

cedreek
In reply to this post by stéphane ducasse-2
2006/8/23, stéphane ducasse <[hidden email]>:
> but is a not the fastest one?
> because you nearly only call primitives?
>
> I did not check.
> Cedric did you benchmark a and c.
> even if large dictionaries degenerate in Squeak.
>
>

not yet but I will when some spare time ;)
Though it probably depends on the kind of collection used...

to benchmark, you'll use  Time milisecondsToRun: [...]
this is what I do ... but I don't know if there are other options...

anyway, I'm not realy concerned by performance issue ;)  but I like to know ;)

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

cedreek
In reply to this post by Ralph Johnson
> This can be fast if collection is an array and if you say "1 to:
> collection do: [:index | ..."
> instead of creating an interval.  The compiler cheats for to:do: on a
> SmallInteger and doesn't create the block.  But I would only use this
> if the profiler showed it was a real improvement.  Almost always I
> would use option C.

same here or the method Bert has given.. #withIndexDo:
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Marcus Denker
In reply to this post by cedreek

On 24.08.2006, at 13:58, cdrick wrote:
>
> to benchmark, you'll use  Time milisecondsToRun: [...]
> this is what I do ... but I don't know if there are other options...


There is #bench:

[100 factorial] bench

        -->  '7888.82223555289 per second.'
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: collection enumeration

Mathieu SUEN
In reply to this post by cedreek
cdrick a écrit :
>> This can be fast if collection is an array and if you say "1 to:
>> collection do: [:index | ..."
>> instead of creating an interval.  The compiler cheats for to:do: on a
>> SmallInteger and doesn't create the block.  But I would only use this
>> if the profiler showed it was a real improvement.  Almost always I
>> would use option C.
>
> same here or the method Bert has given.. #withIndexDo:


It's strange that we have #withIndexDo: and #keysAndValuesDo: doing the
same things on SequenceableCollection.

For me #keysAndValuesDo: take more sense in a dictionary. (?)

Math
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners