On Jan 15, 2013, at 1:58 PM, Brendan Eich wrote:

> The GC cost is one problem, but the property access cost is another, and the 
> second allocation (wm for every obj) yet another. And as Dean just reminded, 
> prototypal inheritance favors symbols. It's not just one cost that motivates 
> symbols over weakmaps if the goal is OO privacy.

Let's consider the just the GC implications  of private symbols versus WeakMaps 
for a very simple integrity use case -- branding.

Let's assume that we have a class of small, highly ephemeral objects that some 
important part of a system is very dependent upon. The integrity of the system 
requires that the instances be well-formed.  Also, these objects are created 
and discarded at a high rate. (for example, perhaps some kind of Point object 
that implements some sort of algorithm optimized coordinate encoding). So, we 
want to "brand" valid instances so that algorithms that consume such objects 
can ensure that they are dealing with the real thing.

There are, at least, two ways to implement this. One way is to use a WeakMap as 
a registry for all valid instances of the class.  The other is to use a private 
Symbol keyed property on each instance as the brand.

Now, before going on we need to understand a few thinks about modern high 
performance garbage collectors.  One principle that applies to them is that 
when dealing with very ephemeral objects you want the complexity of the GC 
algorithms to be proportional to the number of retained (ie, non-garbage) 
objects processed rather than the number of allocated or garbage objects.  This 
is because typical application algorithms that use short-lived objects often 
allocated orders of magnitude more  object than actually remain alive when an 
GC actually occurs.  This characteristic is foundational to generational GCs.   
When it is time to scavenge the nursery, you don't want the GC to have to look 
at 10s of thousands of allocated Points if only dozens are actually alive at 
that point in time.  Scavenging ephemeral collectors are fast and low overhead 
because they only have to inspect or manipulate the actual survivors.  It 
doesn't matter now many now dead objects were allocated, because th
 e GC doesn't even look at them.

Use of a private Symbol for branding has no impact upon this GC behavior.  The 
brand is just an object property and if an ephemeral branded object is 
unreachable it will never be inspected by the GC.

Now consider the impact upon the GC of using WeakMaps for branding.

To start with, WeakMaps uses ephemeron algorithms  that add an extra phase to 
the GC process and (ignoring other overhead) the cost of this phase will be 
proportional to the number of allocated branded objects.  You can over 
simplistically think about it this way: Some WeakDictionary contains an entry 
for every one of the allocated branded objects.  As a final phase of each GC, 
each entry in the WeakDictionary must be examined to determine whether it 
reference an object that was identified as garbage (or conversely, non-garbage) 
by the previous phases of this GC cycle. If an object was identified as garbage 
the final phase of the GC cycle must removed it from the dictionary.  So, even 
though there may only be dozens of surviving branded objects, the GC algorithm 
may have to explicitly process thousands that are garbage.  You have 
essentially lost all the advantage of having a generational ephemeral collector.

Ephemeron-based data structures are great for dealing with a moderate number of 
moderately long-lived objects.  But, if you care about overall system 
performance you don't want to use them to manage high volumes of very ephemeral 
 objects.  As someone who has a lot of GC implementation experience I would 
always choose to use a private Symbol over a WeakMap if either alternative can 
work for some particular use case.

Allen


_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to