On notification proxies

Sam Tobin-Hochstadt samth at ccs.neu.edu
Tue Feb 5 04:52:53 PST 2013

On Tue, Feb 5, 2013 at 7:03 AM, David Bruant <bruant.d at gmail.com> wrote:
> > I like the current API better because it allows for a cleaner pairing of pre
> > and post-traps, including the ability to share private intermediate state
> > through closure capture.
> I have to admit, I'm a bit sad to loose that too. But that's the price to
> pay to get rid of invariant checks I think. It remains possible for pre/post
> trap to share info through the handler.

I've been holding off on this because I know that Mark is still
working on notification proxies, but I think this short discussion
encapsulates exactly why notification proxies are a bad idea.  The big
win of notification proxies is that it reduces the cost and complexity
of invariant checks [1]. However, I believe this cost is small, and
more importantly, not that relevant.

As evidence that this cost is small, in our work on chaperones in
Racket [2], a system that's very similar to proxies [3], we measured
the overhead of the invariant checking required.  In real programs,
even when the proxy overhead was more than *half* the total runtime,
the invariant checks never went above 1% of runtime.  Further, the
design of chaperones, in combination with much greater use of
immutable data in Racket, means that many *more* invariant checks were
performed than would be in a comparable JS system, and the Racket
invariant checks would be significantly *more* expensive.

Even more importantly, optimizing the invariant checks is focusing on
the wrong use case.  Regardless of our preferences, very little JS
data is immutable, or requires any invariant checks at all.  We spend
a lot of time focusing on re-implementations of built-in ES and DOM
APIs, which often are non-configurable or non-writable, but this is
not the common case in user-written JS.  Whether it's building
free-standing exotic objects or wrapping existing ones, it's very
likely that this will continue to be the case with proxy-implemented
objects.  We should focus on that case.

In these common cases, I believe that notification proxies are at a
significant disadvantage.  Notification proxies require that all
communication between the handler and the result of an operation
operates via mutation of the target.  This has several problems.
First, it's a tricky pattern that every proxy programmer has to learn,
increasing the burden for an already complex API.  Second, it forces
the use of the "shadow target" pattern in any wrapper, doubling the
number of allocations required.  Third, the complexity of this pattern
will make proxies that use it harder for engines to optimize. Again,
our experience with Racket is relevant here, and we were able to
achieve a 4.5x speedup on microbenchmarks (a bubble-sort of a proxied
array) by adding simple support in the JIT for proxies.

For all of these reasons, I don't think that notification proxies are
the right direction to go.


[1] Tom makes this point explicitly here
[2] http://www.cs.umd.edu/~sstrickl/chaperones/
[3] Tom and I discussed our designs many times while both were under
development.  Note that in some places, the chaperone design is more
similar to "action proxies", but importantly the result of traps is
always relevant.

More information about the es-discuss mailing list