[squeak-dev] Collection's #fold: vs #reduce:
Eliot Miranda
eliot.miranda at gmail.com
Tue Nov 2 18:50:53 UTC 2010
On Tue, Nov 2, 2010 at 11:31 AM, Levente Uzonyi <leves at elte.hu> wrote:
> On Tue, 2 Nov 2010, Eliot Miranda wrote:
>
> Hi Levente,
>>
>> On Tue, Nov 2, 2010 at 10:16 AM, Levente Uzonyi <leves at elte.hu> wrote:
>>
>> Hi,
>>>
>>> we have these two methods which do exactly the same thing. #reduce: was
>>> added by Andreas during the developement of Squeak 4.1. #fold was added
>>> by
>>> Eliot for Cog VMMaker compatibility. One of them is superfluous. I can
>>> image
>>> the following solutions:
>>>
>>> 1) Replace senders of #fold: in VMMaker to use #reduce:, and remove
>>> #fold:
>>> from the image.
>>>
>>> 2) Replace #fold:'s implementation to self reduce: aBlock. I benchmarked
>>> the two methods and #reduce: is a bit faster on CogVM. There's no
>>> difference
>>> on SqueakVM.
>>>
>>>
>> I noticed the same thing. I prefer the fold: implementation so I'm bummed
>> it's slightly slower ;) Personally I like fold: as a name (it's shorter
>> and
>>
>
> The difference is about 1%, but it's reproducible. And yes, the
> implementation of #fold: is a bit nicer. :)
The difference is due to the instantiation "Object new", and instantiation
is slow on the current Cog because I haven't implemented the instantiation
primitives in machine code, and this limitation is hopefully temporary. So
you might leave it be. However, changing the code to use {} for teh
instantiation speeds things up markedly:
Collection>>newFold: binaryBlock
| firstValue nextValue |
firstValue := nextValue := {}.
self do:
[:each |
nextValue := firstValue == nextValue
ifTrue: [each]
ifFalse: [binaryBlock value: nextValue value: each]].
^nextValue == firstValue
ifTrue: [self errorEmptyCollection]
ifFalse: [nextValue]
| c r |
c := #('if' 'it' 'is' 'to' 'be' 'it' 'is' 'up' 'to' 'me').
{ Time millisecondsToRun: [1 to: 1000000 do: [:i| c fold: [:a :b | a, ' ',
b]]].
Time millisecondsToRun: [1 to: 1000000 do: [:i| c newFold: [:a :b | a, ' ',
b]]].
Time millisecondsToRun: [1 to: 1000000 do: [:i| c reduce: [:a :b | a, ' ',
b]]] }
#(5076 5008 5052)
| c |
c := #('if').
{ Time millisecondsToRun: [1 to: 1000000 do: [:i| c fold: [:a :b | a, ' ',
b]]].
Time millisecondsToRun: [1 to: 1000000 do: [:i| c newFold: [:a :b | a, '
', b]]].
Time millisecondsToRun: [1 to: 1000000 do: [:i| c reduce: [:a :b | a, '
', b]]] }
#(247 226 220)
(N.B. the above are rough measurements!!).
So how about changing fold: to replace Object new with {} and keep it?
2¢
Eliot
>
> more cuddly) and since we don't have map: (we have collect:) I don't find
>> the need to use reduce: compelling. But that's my preference. I won't
>> object if you replace fold: with reduce:/ I do note that Gilad used fold:
>> in Newspeak.
>>
>> What do you prefer?
>>
>
> I prefer the second option, because both names are widely used, but some
> people are only aware of the one which their previously used languages have.
> So this way we can avoid questions like "Why isn't there a
> method for folding in Squeak?".
>
>
> Levente
>
>
>
>> What do others prefer?
>>
>> I know, choices, choices :)
>>
>> best
>> Eliot
>>
>>
>>
>>
>>>
>>> Cheers,
>>> Levente
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20101102/bb5bb74b/attachment.htm
More information about the Squeak-dev
mailing list
|