Hi,
I have two other ideas to enhance finalization: 1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can return immediately, because if finalizer is nil, we just have to throw away the associations which key became nil. The suggested change postpones the removal of elements from the dictionary until rehash, grow or a (lucky) removal happens. It can save a lot of time if there are large WeakKeyDictionaries around (which can easily happen if you load Monticello packages). 2. There should be a way to add multiple finalizers for a single object. Currently if you send #toFinalizeSend:to:with: to an object, it creates an ObjectFinalizer and adds it to the current finalization registry. If you send it one more time to the same object, the first finalizer will be lost. I see two possible solutions: (a) change WeakRegistry to store multiple finalizers per object (b) same as (a), but in a subclass of WeakRegistry and Object >> #finalizationRegistry returns and instance of this subclass Ideas? Opinions? Cheers, Levente |
I came to the decision that 1. is a bad idea, because currently there
is no WeakKeyDictionary which has a finalizer, because it's a new feature. This means that every WeakKeyDictionary would keep references to the finalizers until a rehash, grow or a (lucky) removal happens and that may means "almost forever". So the real solution to the slowdown described in 1. is to remove the cache of MCMethodDefinition from WeakArray's weakDependents which is safe to do IMHO. I uploaded an example implementation of 2b to the Inbox, you can try it from an updated trunk image if you execute this: (Installer squeakfoundation project: 'inbox') install: 'System-ul.263.mcz'; install: 'Collections-ul.318.mcz'; install: 'CollectionsTests-ul.148.mcz' I think we can't get much better finalization performance/features without VM support if 2. gets into the Trunk in some form, so I'm going to focus on Streams again. My short term plan is to rewrite all methods which send #*FileNamed: and #close to FileStream (or a subclass) to use the #*FileNamed:do: method. This is better since it ensures that the file is always closed and it's closed at the right time. This will cause changes in a lot of packages. If that's done, I'll try to refactor the #*FileNamed:do: methods to open and close the file without registering it to the finalization registry. This way opening and closing files will cost less if they are used in a limited scope. If that's done too, I'll try to speed up file opening/closing even more. This involves changes of TextConverter and String too. If that's all done, we may use readonly copies of the source files instead of shared globals without much slowdown. In the meantime I'm still working on the method trailer refactorings so accessing source files will be even faster. Levente On Mon, 22 Feb 2010, Levente Uzonyi wrote: > Hi, > > I have two other ideas to enhance finalization: > 1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can return > immediately, because if finalizer is nil, we just have to throw away the > associations which key became nil. The suggested change postpones the removal > of elements from the dictionary until rehash, grow or a (lucky) removal > happens. It can save a lot of time if there are large WeakKeyDictionaries > around (which can easily happen if you load Monticello packages). > 2. There should be a way to add multiple finalizers for a single object. > Currently if you send #toFinalizeSend:to:with: to an object, it creates an > ObjectFinalizer and adds it to the current finalization registry. If you send > it one more time to the same object, the first finalizer will be lost. I see > two possible solutions: > (a) change WeakRegistry to store multiple finalizers per object > (b) same as (a), but in a subclass of WeakRegistry and Object >> > #finalizationRegistry returns and instance of this subclass > > Ideas? Opinions? > > > Cheers, > Levente > > |
As you probably noticed, I pushed the changes which implement 2a to the
Trunk. For 1. I uploaded two packages to the Inbox. To try them evaluate this: (Installer squeakfoundation project: 'inbox') install: 'Monticello-ul.372.mcz'; install: 'Monticello-ul.373.mcz' Levente On Wed, 24 Feb 2010, Levente Uzonyi wrote: > I came to the decision that 1. is a bad idea, because currently there is no > WeakKeyDictionary which has a finalizer, because it's a new feature. This > means that every WeakKeyDictionary would keep references to the finalizers > until a rehash, grow or a (lucky) removal happens and that may means "almost > forever". So the real solution to the slowdown described in 1. is to remove > the cache of MCMethodDefinition from WeakArray's weakDependents which is safe > to do IMHO. > > I uploaded an example implementation of 2b to the Inbox, you can try it from > an updated trunk image if you execute this: > > (Installer squeakfoundation project: 'inbox') > install: 'System-ul.263.mcz'; > install: 'Collections-ul.318.mcz'; > install: 'CollectionsTests-ul.148.mcz' > > > I think we can't get much better finalization performance/features without VM > support if 2. gets into the Trunk in some form, so I'm going to focus on > Streams again. > > My short term plan is to rewrite all methods which send #*FileNamed: and > #close to FileStream (or a subclass) to use the #*FileNamed:do: method. This > is better since it ensures that the file is always closed and it's closed at > the right time. This will cause changes in a lot of packages. > If that's done, I'll try to refactor the #*FileNamed:do: methods to open and > close the file without registering it to the finalization registry. This way > opening and closing files will cost less if they are used in a limited scope. > If that's done too, I'll try to speed up file opening/closing even more. This > involves changes of TextConverter and String too. > If that's all done, we may use readonly copies of the source files instead of > shared globals without much slowdown. > > In the meantime I'm still working on the method trailer refactorings so > accessing source files will be even faster. > > > Levente > > On Mon, 22 Feb 2010, Levente Uzonyi wrote: > >> Hi, >> >> I have two other ideas to enhance finalization: >> 1. If WeakKeyDictionary's finalizer is nil, then #finalizeValues can return >> immediately, because if finalizer is nil, we just have to throw away the >> associations which key became nil. The suggested change postpones the >> removal of elements from the dictionary until rehash, grow or a (lucky) >> removal happens. It can save a lot of time if there are large >> WeakKeyDictionaries around (which can easily happen if you load Monticello >> packages). >> 2. There should be a way to add multiple finalizers for a single object. >> Currently if you send #toFinalizeSend:to:with: to an object, it creates an >> ObjectFinalizer and adds it to the current finalization registry. If you >> send it one more time to the same object, the first finalizer will be lost. >> I see two possible solutions: >> (a) change WeakRegistry to store multiple finalizers per object >> (b) same as (a), but in a subclass of WeakRegistry and Object >> >> #finalizationRegistry returns and instance of this subclass >> >> Ideas? Opinions? >> >> >> Cheers, >> Levente >> >> > > |
Free forum by Nabble | Edit this page |