size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

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

size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

Guillermo Polito
Hi! I wass looking at tha issue, specially at the item that says:

"- ensure that #rehashWithoutBecome doesn't send #become:, making
#rehashAllInstances a lot faster"

And the change made in squeak was:

Item was changed:
 ----- Method: MethodDictionary>>rehashWithoutBecome (in category
'private') -----
 rehashWithoutBecome

+       | newInstance |
+       newInstance := self species new: self basicSize - 1. "Make
sure it has the same capacity"
+       1 to: self basicSize do: [ :index |
+               (self basicAt: index) ifNotNil: [ :key |
+                       newInstance at: key put: (array at: index) ] ].
+       ^newInstance!
-       | newSelf |
-       newSelf := self species new: self size.
-       1 to: self basicSize do: [ :i |
-               | key |
-               (key := self basicAt: i) ifNotNil: [
-                       newSelf at: key put: (array at: i) ] ].
-       ^newSelf!

And I figured out that this change does nothing with its comment
"ensure that #rehashWithoutBecome doesn't send #become:"

Also, the only senders in the Core image are ScriptLoader
SmalltalkImage (and there is no ·#rehashAllInstances ).

------------------------------------------

I tried this code before and after the change

oldDicts := MethodDictionary allInstances.
[ | newDicts | newDicts := Array new: oldDicts size.
        oldDicts withIndexDo: [ :d :index | newDicts at: index put: d
rehashWithoutBecome ].] timeToRun

And I saw a little improvement in performance (but it fluctuated a lot...).

Does anyone know a performance difference between size and basicSize
in Dictionary, HashedCollection or MethodDictionary?

Thanks

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

Levente Uzonyi-2
On Sat, 21 Aug 2010, Guillermo Polito wrote:

> Hi! I wass looking at tha issue, specially at the item that says:
>
> "- ensure that #rehashWithoutBecome doesn't send #become:, making
> #rehashAllInstances a lot faster"
>
> And the change made in squeak was:
>
> Item was changed:
> ----- Method: MethodDictionary>>rehashWithoutBecome (in category
> 'private') -----
> rehashWithoutBecome
>
> +       | newInstance |
> +       newInstance := self species new: self basicSize - 1. "Make
> sure it has the same capacity"
> +       1 to: self basicSize do: [ :index |
> +               (self basicAt: index) ifNotNil: [ :key |
> +                       newInstance at: key put: (array at: index) ] ].
> +       ^newInstance!
> -       | newSelf |
> -       newSelf := self species new: self size.
> -       1 to: self basicSize do: [ :i |
> -               | key |
> -               (key := self basicAt: i) ifNotNil: [
> -                       newSelf at: key put: (array at: i) ] ].
> -       ^newSelf!
>
> And I figured out that this change does nothing with its comment
> "ensure that #rehashWithoutBecome doesn't send #become:"
>
> Also, the only senders in the Core image are ScriptLoader
> SmalltalkImage (and there is no ?#rehashAllInstances ).
>
> ------------------------------------------
>
> I tried this code before and after the change
>
> oldDicts := MethodDictionary allInstances.
> [ | newDicts | newDicts := Array new: oldDicts size.
> oldDicts withIndexDo: [ :d :index | newDicts at: index put: d
> rehashWithoutBecome ].] timeToRun
>
> And I saw a little improvement in performance (but it fluctuated a lot...).
>
> Does anyone know a performance difference between size and basicSize
> in Dictionary, HashedCollection or MethodDictionary?

1. #basicSize is only meaningful for MethodDictionary, for other
HashedCollections it's not related to the elements of the collection (at
least in Squeak).
2. The performance difference (in Squeak) comes from the fact that if
#size returns a power of two, then (with the old code) the
MethodDictionary will grow when the last element is inserted by the loop.
During the growth all elements will be hashed again and #become: will be
used to swap the old and the new MethodDictionary, which is "very slow" in
Squeak (and in Pharo).

So if you apply the change and you have a few MethodDictionaries with
power of two size in your image and all relevant changes from Squeak are
applied, then you should see the speedup.

All in all: in Squeak without this patch #rehashWithoutBecome could send
#become: in the "background".


Levente

>
> Thanks
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

Guillermo Polito
So, is it safe to integrate?

Guille

On Sat, Aug 21, 2010 at 9:06 PM, Levente Uzonyi <[hidden email]> wrote:

> On Sat, 21 Aug 2010, Guillermo Polito wrote:
>
>> Hi! I wass looking at tha issue, specially at the item that says:
>>
>> "- ensure that #rehashWithoutBecome doesn't send #become:, making
>> #rehashAllInstances a lot faster"
>>
>> And the change made in squeak was:
>>
>> Item was changed:
>> ----- Method: MethodDictionary>>rehashWithoutBecome (in category
>> 'private') -----
>> rehashWithoutBecome
>>
>> +       | newInstance |
>> +       newInstance := self species new: self basicSize - 1. "Make
>> sure it has the same capacity"
>> +       1 to: self basicSize do: [ :index |
>> +               (self basicAt: index) ifNotNil: [ :key |
>> +                       newInstance at: key put: (array at: index) ] ].
>> +       ^newInstance!
>> -       | newSelf |
>> -       newSelf := self species new: self size.
>> -       1 to: self basicSize do: [ :i |
>> -               | key |
>> -               (key := self basicAt: i) ifNotNil: [
>> -                       newSelf at: key put: (array at: i) ] ].
>> -       ^newSelf!
>>
>> And I figured out that this change does nothing with its comment
>> "ensure that #rehashWithoutBecome doesn't send #become:"
>>
>> Also, the only senders in the Core image are ScriptLoader
>> SmalltalkImage (and there is no ?#rehashAllInstances ).
>>
>> ------------------------------------------
>>
>> I tried this code before and after the change
>>
>> oldDicts := MethodDictionary allInstances.
>> [ | newDicts |  newDicts := Array new: oldDicts size.
>>        oldDicts withIndexDo: [ :d :index | newDicts at: index put: d
>> rehashWithoutBecome ].] timeToRun
>>
>> And I saw a little improvement in performance (but it fluctuated a
>> lot...).
>>
>> Does anyone know a performance difference between size and basicSize
>> in Dictionary, HashedCollection or MethodDictionary?
>
> 1. #basicSize is only meaningful for MethodDictionary, for other
> HashedCollections it's not related to the elements of the collection (at
> least in Squeak).
> 2. The performance difference (in Squeak) comes from the fact that if #size
> returns a power of two, then (with the old code) the MethodDictionary will
> grow when the last element is inserted by the loop. During the growth all
> elements will be hashed again and #become: will be used to swap the old and
> the new MethodDictionary, which is "very slow" in Squeak (and in Pharo).
>
> So if you apply the change and you have a few MethodDictionaries with power
> of two size in your image and all relevant changes from Squeak are applied,
> then you should see the speedup.
>
> All in all: in Squeak without this patch #rehashWithoutBecome could send
> #become: in the "background".
>
>
> Levente
>
>>
>> Thanks
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

Levente Uzonyi-2
On Sat, 21 Aug 2010, Guillermo Polito wrote:

> So, is it safe to integrate?

If you're asking me, I don't know for sure, because I don't use Pharo. But
it's probably safe.


Levente

>
> Guille
>
> On Sat, Aug 21, 2010 at 9:06 PM, Levente Uzonyi <[hidden email]> wrote:
>> On Sat, 21 Aug 2010, Guillermo Polito wrote:
>>
>>> Hi! I wass looking at tha issue, specially at the item that says:
>>>
>>> "- ensure that #rehashWithoutBecome doesn't send #become:, making
>>> #rehashAllInstances a lot faster"
>>>
>>> And the change made in squeak was:
>>>
>>> Item was changed:
>>> ----- Method: MethodDictionary>>rehashWithoutBecome (in category
>>> 'private') -----
>>> rehashWithoutBecome
>>>
>>> +       | newInstance |
>>> +       newInstance := self species new: self basicSize - 1. "Make
>>> sure it has the same capacity"
>>> +       1 to: self basicSize do: [ :index |
>>> +               (self basicAt: index) ifNotNil: [ :key |
>>> +                       newInstance at: key put: (array at: index) ] ].
>>> +       ^newInstance!
>>> -       | newSelf |
>>> -       newSelf := self species new: self size.
>>> -       1 to: self basicSize do: [ :i |
>>> -               | key |
>>> -               (key := self basicAt: i) ifNotNil: [
>>> -                       newSelf at: key put: (array at: i) ] ].
>>> -       ^newSelf!
>>>
>>> And I figured out that this change does nothing with its comment
>>> "ensure that #rehashWithoutBecome doesn't send #become:"
>>>
>>> Also, the only senders in the Core image are ScriptLoader
>>> SmalltalkImage (and there is no ?#rehashAllInstances ).
>>>
>>> ------------------------------------------
>>>
>>> I tried this code before and after the change
>>>
>>> oldDicts := MethodDictionary allInstances.
>>> [ | newDicts |  newDicts := Array new: oldDicts size.
>>>        oldDicts withIndexDo: [ :d :index | newDicts at: index put: d
>>> rehashWithoutBecome ].] timeToRun
>>>
>>> And I saw a little improvement in performance (but it fluctuated a
>>> lot...).
>>>
>>> Does anyone know a performance difference between size and basicSize
>>> in Dictionary, HashedCollection or MethodDictionary?
>>
>> 1. #basicSize is only meaningful for MethodDictionary, for other
>> HashedCollections it's not related to the elements of the collection (at
>> least in Squeak).
>> 2. The performance difference (in Squeak) comes from the fact that if #size
>> returns a power of two, then (with the old code) the MethodDictionary will
>> grow when the last element is inserted by the loop. During the growth all
>> elements will be hashed again and #become: will be used to swap the old and
>> the new MethodDictionary, which is "very slow" in Squeak (and in Pharo).
>>
>> So if you apply the change and you have a few MethodDictionaries with power
>> of two size in your image and all relevant changes from Squeak are applied,
>> then you should see the speedup.
>>
>> All in all: in Squeak without this patch #rehashWithoutBecome could send
>> #become: in the "background".
>>
>>
>> Levente
>>
>>>
>>> Thanks
>>>
>>> _______________________________________________
>>> Pharo-project mailing list
>>> [hidden email]
>>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>>
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: size vs basic and SizeMethodDictionary>>rehashWithoutBecome - Issue 1899

Stéphane Ducasse
In reply to this post by Levente Uzonyi-2
I really like this change because I would really like to have a kernel with as few as become: as possible.
Thanks for answering the questions of guillermo and guillermo thanks for checking, asking and that we learn all.

Stef


> On Sat, 21 Aug 2010, Guillermo Polito wrote:
>
>> Hi! I wass looking at tha issue, specially at the item that says:
>>
>> "- ensure that #rehashWithoutBecome doesn't send #become:, making
>> #rehashAllInstances a lot faster"
>>
>> And the change made in squeak was:
>>
>> Item was changed:
>> ----- Method: MethodDictionary>>rehashWithoutBecome (in category
>> 'private') -----
>> rehashWithoutBecome
>>
>> +       | newInstance |
>> +       newInstance := self species new: self basicSize - 1. "Make
>> sure it has the same capacity"
>> +       1 to: self basicSize do: [ :index |
>> +               (self basicAt: index) ifNotNil: [ :key |
>> +                       newInstance at: key put: (array at: index) ] ].
>> +       ^newInstance!
>> -       | newSelf |
>> -       newSelf := self species new: self size.
>> -       1 to: self basicSize do: [ :i |
>> -               | key |
>> -               (key := self basicAt: i) ifNotNil: [
>> -                       newSelf at: key put: (array at: i) ] ].
>> -       ^newSelf!
>>
>> And I figured out that this change does nothing with its comment
>> "ensure that #rehashWithoutBecome doesn't send #become:"
>>
>> Also, the only senders in the Core image are ScriptLoader
>> SmalltalkImage (and there is no ?#rehashAllInstances ).
>>
>> ------------------------------------------
>>
>> I tried this code before and after the change
>>
>> oldDicts := MethodDictionary allInstances.
>> [ | newDicts | newDicts := Array new: oldDicts size.
>> oldDicts withIndexDo: [ :d :index | newDicts at: index put: d
>> rehashWithoutBecome ].] timeToRun
>>
>> And I saw a little improvement in performance (but it fluctuated a lot...).
>>
>> Does anyone know a performance difference between size and basicSize
>> in Dictionary, HashedCollection or MethodDictionary?
>
> 1. #basicSize is only meaningful for MethodDictionary, for other HashedCollections it's not related to the elements of the collection (at least in Squeak).
> 2. The performance difference (in Squeak) comes from the fact that if #size returns a power of two, then (with the old code) the MethodDictionary will grow when the last element is inserted by the loop. During the growth all elements will be hashed again and #become: will be used to swap the old and the new MethodDictionary, which is "very slow" in Squeak (and in Pharo).
>
> So if you apply the change and you have a few MethodDictionaries with power of two size in your image and all relevant changes from Squeak are applied, then you should see the speedup.
>
> All in all: in Squeak without this patch #rehashWithoutBecome could send #become: in the "background".
>
>
> Levente
>
>>
>> Thanks
>>
>> _______________________________________________
>> Pharo-project mailing list
>> [hidden email]
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project