WeakMap.prototype.clear performance (was: Questioning WeakMap.prototype.clear)

David Bruant bruant.d at gmail.com
Tue Jan 22 11:55:54 PST 2013

[Merging a couple of relevant posts]

Le 22/01/2013 15:59, Jason Orendorff a écrit :
>     Now, the only thing that can differentiate both the native against
>     this version is performance I think. Allen seems to argue that a
>     native .clear would have better perf characteristics (related to
>     GC). I still fail to see why the difference would be significant
>     (but I need to re-read his recent posts about that).
> Definitely re-read them. They made sense to me. If you have questions 
> about the implementation of GC through WeakMaps, I'll happily share 
> what I know.
That would be:
* https://mail.mozilla.org/pipermail/es-discuss/2013-January/028145.html
* https://mail.mozilla.org/pipermail/es-discuss/2013-January/028387.html

>     As an implementor, what is your feeling about performance
>     characteristics of both the native and the class-based version?
> Heh! I'm the worst person to ask about this. I'm not comfortable with 
> the worst-case GC performance of WeakMaps to begin with. My main 
> coping mechanism is not thinking about it!
> In our current implementation, creating a new WeakMap and dropping the 
> old one is very nearly equivalent in performance to clear(). However 
> that's because we don't have a generational GC today. Dead WeakMaps 
> are promptly collected. In another year, that will change. If we end 
> up with more than two generations, I think it'll lead to exactly the 
> problems Allen foresees.
For reference, quote from Allen:
> generational collectors can have large latencies between the time the 
> last reference to an object is destroyed and the when the GC actually 
> notices.  Many GC cycles may occur during that period and if a 
> populated but unneeded large WeakMap is one of these zombie object, 
> then it can have perf impacts.
> Maybe even if we just have two generations. (To some extent, 
> long-lived ordinary Maps and Arrays also do this in a generational GC; 
> but WeakMaps have much, much worse worst-case GC performance.)
Indeed, the long-lived object being the only root of a big graph is a 
problem unrelated to WeakMaps. If that was the only reason to add a 
clear method on weakmaps, an Object.clear should be considered too.
I don't understand the point about the worst-case GC performance. It may 
be related to Allen's point about ephemeron algorithms which I know not 
enough about.
I would be interested in knowing more if that's relevant. I'm not 
entirely sure it's relevant since the difference between .clear and 
dropping a weakmap is about the delta during which the storage is 
considered collectable.

> Having said all that, I bet we could hack around the worst-case GC 
> performance. It'll be a pain, but GC is like that sometimes.
What you said above about the current GC setup that yields equivalence 
performance to .clear is interesting. In a nutshell, moving to a 
(naive?) generational GC means that you're losing something you had 
before. I feel there is a middleground to be found. What about the 
WeakMaps are allocated in their own area which is manually GC'ed with 
today's algorithm (which is probably implemented for the last 
generation?). This way, you'll know as soon as possible (next GC) if one 
is dead.
* WeakMaps are moved to this area after a given threshold (20 keys?)
* WeakMaps are moved to this area if they survives one GC. cycle
I feel that with this dedicated area, you know soon enough (next GC 
which is what you get for .clear too) whether a big weakmap can be 

I wouldn't consider what I suggested as a hack around worst-case GC 
performance, but rather as WeakMap special-casing. Given WeakMaps 
special properties about memory management, it doesn't sound that crazy 
to special case how they're being used in GC algorithms.
Maybe the ideas I suggested above in 5 minutes are not perfect, but I 
feel special-casing weakmaps is a direction to explore regardless of the 
debate we're having about .clear actually since developers won't 
necessarily always use it and the GC needs to be fast in these cases too.

Just to be sure I understand generational GC: old generations considered 
as roots when doing most GC traversing, right? That's why it may take 
time to realize they're actually dead?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130122/20a81105/attachment-0001.html>

More information about the es-discuss mailing list