> The properties already existed, so defineProperty shouldn't modify the order IIUC
well, nope. the property existed in the prototype, not in the object. anyway, I guess private properties, that are a possible solution, will be transpiled through a WeakMap so that most likely anything discussed in here won't make sense and the future code would look like the following ```js class A { #random; get random() { return this.#random || (this.#random = Math.random()); } } // transpiled var A = function (wm) { function A() { wm.set(this, {random: void 0}); } Object.defineProperties( A.prototype, { random: { configurable: true, get: function () { return wm.get(this).random || (wm.get(this).random = Math.random()); } } } ); return A; }(new WeakMap); ``` On Tue, Sep 12, 2017 at 10:39 PM, Steve Fink <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 <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 < >> 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 <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 >> 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