Re: [Pharo-project] [squeak-dev] How weak finalization affects the performance
On 26 October 2010 10:30, Andres Valloud <avalloud@smalltalk.comcastbiz.net> 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.
participants (1)
-
Igor Stasenko