I think to the degree that almost anyone would care, the public and private key 
proposal would address most of these issues. The private keys would not be 
affected by object shape so would have rip-roaring good performance. You'd 
simply need to provide getter functions in the prototype that check for 
undefined (or whatever) in the private variable, if not undefined return value, 
otherwise calculate value, set private variable, and return the value. Unless 
you're trying to calculate pi to a million decimal places this should be pretty 
much good enough for anything.

And it gives you the encapsulation you get in many other programming languages 
such as Java and C++. Public JS APIs would end up looking a lot like these for 
many applications -- a bunch of private variables and public functions 
including getters and setters. 

Basically, most of our code already looks like this but we use closures rather 
than private variable to accomplish this. And yes, there is a dark side to 
closures, specifically the challenge in implementing closed function that don't 
gobble up a lot of memory. In V8 if I construct an object with say 20 function 
properties that's 20 JSFunction objects V8 has to create, each one being on the 
order of 72 bytes per function. It's not too horrible if we don't have a lot of 
these and they have relatively long lives but problematic for lots of 
instantiation of objects with lots of functions. The private key proposal would 
address this issue. 

----
Alex Kodat

From: es-discuss [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Matthew 
Robb
Sent: Tuesday, September 12, 2017 4:49 PM
To: Steve Fink <sph...@gmail.com>
Cc: es-discuss@mozilla.org >> es-discuss <es-discuss@mozilla.org>
Subject: Re: Lazy evaluation

I think it would be nice to be able to define an own data property on an object 
that while defined delegated up the prototype chain. This would allow a getter 
in the proto to lazily assign to the own property without triggering the 
property setter. This is even more nice when combined with super as you could 
conceivably hit the setter which itself could assign to the own property of the 
current instance.

Is that all too complicated? It seems perfect if only a little complicated.

On Sep 12, 2017 5:39 PM, "Steve Fink" <mailto:sph...@gmail.com> wrote:
My intent was only to respond to the performance analysis, specifically the 
implication that the only performance cost is in building the new hidden class. 
That is not the case; everything that touches those objects is affected as well.

Whether or not it's still the right way to accomplish what you're after, I 
wasn't venturing an opinion. I could probably come up with a benchmark showing 
that your WeakMap approach can be faster -- eg by only accessing the property 
once, but feeding the old and new versions of the object into code that 
executes many many many times (doing something that never looks at that 
property, but is now slightly slower because it isn't monomorphic). But I 
suspect that for practical usage, redefining the property *is* faster than a 
WeakMap.

If I were to look beyond for other solutions for your problem, then I'm just 
speculating. Can decorators populate multiple properties once the expensive 
work is done?

I really want to tell the VM what's going on. I guess if it knew that accessing 
a getter property would convert it into a value property, and that it was doing 
something that would access the getter, then it could know to use the outgoing 
shape instead of the incoming shape. If only it knew that the getter was 
pure... but that way lies madness.

Given that most code that would slow down would also trigger the lazy 
defineProperty(), it's really not going to be that much of an issue. Any access 
after the first will see a single shape.

meh. Just take the perf hit, with awareness that you may be triggering slight 
slowdowns in all users of that object. Or you might not. I doubt it'll be that 
big, since you'll probably just end up with an inline cache for both shapes and 
there won't be all that much to optimize based on knowing a single shape.

Oh, and I think I was wrong about property enumeration order. The properties 
already existed, so defineProperty shouldn't modify the order IIUC. (I am awful 
with language semantics.)

On 9/11/17 2:48 PM, Andrea Giammarchi wrote:
Steve it's not solved in any other way. Even if you use a WeakMap with an 
object, you gonna lazy attach properties to that object. 

I honestly would like to see alternatives, if any, 'cause so far there is a 
benchmark and it proves already lazy property assignment is around 4x faster.

So, it's easy to say "it's not the best approach" but apparently hard to prove 
that's the case?

Looking forward to see better alternatives.


On Mon, Sep 11, 2017 at 8:15 PM, Steve Fink <mailto:sph...@gmail.com> wrote:
On 9/11/17 5:36 AM, Matthew Robb wrote:
> I think it's irrelevant if internally VMs are not too happy. VMs are there to 
> solve our problems, not vice-versa ;-)
​
This ^​ is very important for everyone to get on board with. Regardless the 
cost should be negligible as the shape is only changing at the point of delayed 
init. This will cause, for example V8, to deop the object and have to build a 
new hidden class but only the one time. I guess it would potentially be 
interesting to support an own property that when undefined would delegate up 
the proto chain.

(I don't know, but) I would expect it to be worse than this. The shape is 
changing at the point of delayed init, which means that if an engine is 
associating the possible set of shapes with the constructor (or some other form 
of allocation site + mandatory initialization), then that site will produce 
multiple shapes. All code using such objects, if they ever see both shapes, 
will have to handle them both. Even worse, if you have several of these delayed 
init properties and you end up lazily initializing them in different orders 
(which seems relatively easy to do), then the internal slot offsets will vary.

You don't need to bend over backwards to make things easy for the VMs, but you 
don't want to be mean to them either. :-)

Not to mention that the observable property iteration order will vary.

On Mon, Sep 11, 2017 at 7:09 AM, Andrea Giammarchi 
<mailto:andrea.giammar...@gmail.com> wrote:

Hi Peter. 

Unless you have a faster way to do lazy property assignment, I think it's 
irrelevant if internally VMs are not too happy. VMs are there to solve our 
problems, not vice-versa ;-)

Regards



On Mon, Sep 11, 2017 at 11:54 AM, peter miller 
<mailto:fuchsia.gr...@virgin.net> wrote:
Hi Andrea,
```
class CaseLazy {
  get bar() {
    var value = Math.random();
    Object.defineProperty(this, 'bar', {value});
    return value;
  }
}
```

Doesn't this count as redefining the shape of the object? Or are the compilers 
fine with it?


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



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

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

Reply via email to