How weak finalization affects the performance

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

How weak finalization affects the performance

Igor Stasenko
Here the idea, which came to Chris,
put a delay into #finalizationProcess loop:

finalizationProcess
        [true] whileTrue:
                [ WeakFinalizationList initTestPair.
                FinalizationSemaphore wait.
                FinalizationLock critical:
                        [
                        WeakFinalizationList checkTestPair.
                        FinalizationDependents do:
                                [:weakDependent |
                                weakDependent ifNotNil:
                                        [weakDependent finalizeValues]]]
                        ifError:
                        [:msg :rcvr | rcvr error: msg].
                5 seconds asDelay wait.
                ].


And here a simple benchmark, which triggers GC often:

[ Array new: 100 ] bench

without delay:

'2,450,000 per second.'
'2,490,000 per second.'
'2,490,000 per second.'
'2,480,000 per second.'
'2,530,000 per second.'

with delay:

'2,670,000 per second.'
'2,680,000 per second.'
'2,690,000 per second.'
'2,730,000 per second.'

roughly about ~8% faster :)

But now lets put something big into weak array:

| dict b |
dict := WeakKeyDictionary new addAll: (( 1 to: 1000 ) collect: [:i |
i->i] ); yourself.
WeakArray addWeakDependent: dict.
b := [ Array new: 100 ] bench.
WeakArray removeWeakDependent: dict.
b

without delay:

'1,840,000 per second.'
'2,060,000 per second.'
'2,130,000 per second.'

with delay:

'3,030,000 per second.'
'2,880,000 per second.'
'2,890,000 per second.'

Do not forget to do:
WeakArray restartFinalizationProcess

when you changing the #finalizationProcess method,
otherwise you won't see real numbers.

So, i like the idea of putting delay there.
Finalization is eventual, and there is no hard guarantees that it will
happen in micro-second just after some object become garbage.
So, be it 5 seconds or 1000 seconds not really matters.
What is matters that with delay we win much more, by avoiding wasting
time in finalization process too often.


--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
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: [squeak-dev] How weak finalization affects the performance

Igor Stasenko
On 26 October 2010 10:30, Andres Valloud
<[hidden email]> wrote:
> Why does finalization do any work when running a block which I think just
> creates garbage?  Is finalization on a per class basis (i.e.: the VM
> notifies the image that some objects might be notified, and the image just
> enumerates through them), or on a per object basis (i.e.: the VM maintains a
> finalization queue as in VisualWorks)?
>

There is no per-object or per-class finalization in Squeak. One must
either register an object using WeakRegistry,
or add own object to weak dependents (it should answer to #finalizeValues).
Squeak VM signals the semaphore each time GC happen,
and actually, a finalization process could do something arbitrary to
react on such event.
Putting delay there ensuring that even if you put a very ineffective
finalization into weak dependents,
it won't affect the performance too much.

> On 10/26/10 0:25 , Igor Stasenko wrote:
>>
>> Here the idea, which came to Chris,
>> put a delay into #finalizationProcess loop:
>>
>> finalizationProcess
>>        [true] whileTrue:
>>                [ WeakFinalizationList initTestPair.
>>                FinalizationSemaphore wait.
>>                FinalizationLock critical:
>>                        [
>>                        WeakFinalizationList checkTestPair.
>>                        FinalizationDependents do:
>>                                [:weakDependent |
>>                                weakDependent ifNotNil:
>>                                        [weakDependent finalizeValues]]]
>>                        ifError:
>>                        [:msg :rcvr | rcvr error: msg].
>>                5 seconds asDelay wait.
>>                ].
>>
>>
>> And here a simple benchmark, which triggers GC often:
>>
>> [ Array new: 100 ] bench
>>
>> without delay:
>>
>> '2,450,000 per second.'
>> '2,490,000 per second.'
>> '2,490,000 per second.'
>> '2,480,000 per second.'
>> '2,530,000 per second.'
>>
>> with delay:
>>
>> '2,670,000 per second.'
>> '2,680,000 per second.'
>> '2,690,000 per second.'
>> '2,730,000 per second.'
>>
>> roughly about ~8% faster :)
>>
>> But now lets put something big into weak array:
>>
>> | dict b |
>> dict := WeakKeyDictionary new addAll: (( 1 to: 1000 ) collect: [:i |
>> i->i] ); yourself.
>> WeakArray addWeakDependent: dict.
>> b := [ Array new: 100 ] bench.
>> WeakArray removeWeakDependent: dict.
>> b
>>
>> without delay:
>>
>> '1,840,000 per second.'
>> '2,060,000 per second.'
>> '2,130,000 per second.'
>>
>> with delay:
>>
>> '3,030,000 per second.'
>> '2,880,000 per second.'
>> '2,890,000 per second.'
>>
>> Do not forget to do:
>> WeakArray restartFinalizationProcess
>>
>> when you changing the #finalizationProcess method,
>> otherwise you won't see real numbers.
>>
>> So, i like the idea of putting delay there.
>> Finalization is eventual, and there is no hard guarantees that it will
>> happen in micro-second just after some object become garbage.
>> So, be it 5 seconds or 1000 seconds not really matters.
>> What is matters that with delay we win much more, by avoiding wasting
>> time in finalization process too often.
>>
>>
>
>



--
Best regards,
Igor Stasenko AKA sig.

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