Re: A case for removing the seal/freeze/isSealed/isFrozen traps
2013/2/14 Allen Wirfs-Brock al...@wirfs-brock.com On Feb 13, 2013, at 12:53 PM, David Bruant wrote: Interesting. So what would happen when calling Object.isFrozen on a proxy? Would Object.isFrozen/isSealed/isExtensible reach out directly to the target? or a unique state trap returning a string for all of them? (state is too generic of a name, but you get the idea) This is a question regarding proxy design, rather than the MOP. Either get/setIntegrity traps to the handler or it forwards directly to the target. That's would be a design issue for Tom, but my starting point is to simply follow the current design decisions made for [[PreventExtensions]]/[[IsExtensible]] A get/setIntegrity trap with the invariant constraints of isExtensible/preventExtensions would be the obvious path to take. One thing that remains unclear to me: if the state of an object becomes explicit, we introduce the risk for this state to become inconsistent with the state from which it is derived. For example, setting the integrity of an object to frozen must still make all own properties non-configurable, i.e. Reflect.setIntegrity(obj, frozen) should have the same effect as Object.freeze(obj) Likewise, turning the last configurable property of a non-extensible object into a non-configurable property should automagically change the state to frozen, i.e. Object.defineProperty(obj, lastProperty, { configurable: false }) // must update internal state as well as the property Reflect.getIntegrity(obj) === frozen Will this not just shift the current complexity someplace else? Regardless on the final decision on (full) notification proxies, maybe these operations (isSealed/isFrozen) could have notification trap. The invariant is that the answer has to be the target one (all the time), so the trap return value is irrelevant. Like the getPrototypeOf trap. Right, one way or another these operations need to be part of the MOP. If we go for get/setIntegrity I wouldn't re-introduce all the derived operations as notification traps. Then we might as well leave things the way they are. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Private symbols vs property attributes
2013/2/13 David Bruant bruan...@gmail.com The trap in itself no, but it's possible to keep track of all exchanged symbols and add them to the whitelists as they are observed before being shared. It all relies on the fact that for 2 parties to exchange symbols, they have to share it through a public communication first (get trap, etc.). At some point, I thought it had a runtime cost, but Tom proved me wrong [1]. It seems realistic to consider that all proxies of the same membrane can all share the same set instance as a whitelist making the space cost as small as it could be. This doesn't solve Mark's use case: he wants to be able to share symbols freely among trust boundaries without those symbols necessarily flowing through a membrane. At that point, there's no way for the proxy to intercept the symbol and add it to its whitelist, and transparency is broken. As I said before, I think Andreas' proposal is agnostic to the interaction between proxies and symbols. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
Hey Allen, thanks for clarifying. What will happen to other Array methods which currently return Arrays? `filter` is the primary one that comes to mind. Will `uint32array.filter((v) = v != 0)` return a Uint32Array? (I think it should behave the same way `map` does.) Additionally, what will happen with the return values of `slice`, `splice`, and `reverse`?.. not to mention `concat`, which I know is a much more complex beast. Nathan Subject: Re: Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes) From: al...@wirfs-brock.com Date: Wed, 13 Feb 2013 17:49:27 -0700 CC: claus.rei...@talk21.com; e-t...@ecma-international.org; es-discuss@mozilla.org To: nathan.w...@live.com On Feb 11, 2013, at 7:13 PM, Nathan Wall wrote: Thank you for this explanation. This is very interesting! If you don't mind, I have some questions/concerns I'd like to clear up. (In particular I want to make sure I understand; I don't intend to argue for one side or the other ATM, but this change may require me to refactor some old code to be future-ready). Allen Wirfs-Brock wrote: The choice we agreed to, at the meeting is 1) Array.prototype.map produces the same kind of array that it was applied to, so: for the above example m instance of V will be true. intArray.map(v=v.toSring()) produces an Int32Array. The strings produced by the map function get converted back to numbers. Sounds cool! Does it work? I rely on the genericness of Array methods quite a lot. For example, it's fairly common for me to write something like the following: var map = Function.prototype.call.bind(Array.prototype.map), select = document.querySelectorAll.bind(document); var ids = map(select('div'), function(el) { return el.id; }); Currently this would get me an array of string ids for every div on a page. In a future ES6 with a future DOM where NodeList extends Array, will `ids` no longer hold an array of strings but try to remain a NodeList? Anything that works with ES5 semantics should continue to work, assuming nothing else changes. If NodeList was turned into an actual subclass of Array, then the default behavior of Array.prototype.map when applied to a NodeList will be to create a new NodeList, assuming that NodeList supports all the mechanism that map uses to create its result object. Of course, the design of this new NodeList has the option of over-riding the inherited definition of map and/or opt-ing out of the create something other than Array instance behavior. Regardless, because of backwards compatibility concerns, I'm skeptical that NodeList could ever be made into an Array subclass. It seems more likely that a new kind of DOM Node collection that was an Array subclass might be introduced There's a good chance this will break some of my code. I'm capable of changing my code and writing this to be more future-friendly from now on (I'm not one who prefers backwards compatibility over a better language). But I would have always assumed I was doing things correctly before, and I'm curious if the rest of the internet will be okay..? We can't break existing code. Where things get messy is when old code is combined with new code that uses new features. For example, you map function will produce a SubArray instance if it is called with a SubArray instance assuming that SubArray is a real ES6 subclass of Array as its first argument. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
On 14 February 2013 02:35, Allen Wirfs-Brock al...@wirfs-brock.com wrote: As we discussed at the meeting, to rationally place Typed Arrays into the same class hierarchy as Array would require refactoring Array.prototype into multiple abstract superclasses. This seems like too large of a change. Instead the plan that we agreed to is to introduce TypedArray as an abstract superclass of all of the specific Typed Array constructors. TypedArray.prototype will be specified to have all of the Array.prototype methods that don't dynamic change the length of an array. (TypedArray.prototype will also define set and subarray from the Khronos Typed Array spec.) I'm still not convinced that introducing a separate class only for masking a handful of length-modifying array methods is worthwhile. After all, ordinary arrays can be sealed or frozen, too, while still providing those methods, so typed arrays are not new or different in that regard. I'd say that either we properly clean up the Array hierarchy, or we leave it alone. A half-baked solution that only applies to typed arrays, and divorces them from the Array hierarchy, seems less attractive than just doing the naive thing, i.e., TypedArray Array. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
On 13 February 2013 13:39, David Bruant bruan...@gmail.com wrote: Warning: In this post, I'll be diverging a bit from the main topic. Le 12/02/2013 14:29, Brendan Eich a écrit : Loss of identity, extra allocations, and forwarding overhead remain problems. I'm doubtful loss of identity matters often enough to be a valid argument here. I'd be interested in being proved wrong, though. I understand the point about extra allocation. I'll talk about that below. The forwarding overhead can be made inexistent in the very case I've exposed because in the handler, the traps you care about are absent from the handler, so engines are free to optimize the [[Get]]friends as operations applied directly to the target. You're being vastly over-optimistic about the performance and the amount of optimisation that can realistically be expected for proxies. Proxies are inherently unstructured, higher-order, and effectful, which defeats most sufficiently simple static analyses. A compiler has to work much, much harder to get useful results. Don't expect anything anytime soon. I've seen this in a previous experience on a Chrome extension where someone would seal an object as a form of documentation to express I need these properties to stay in the object. It looked like: function C(){ // play with |this| return Object.seal(this) } My point here is that people do want to protect their object integrity against untrusted parties which in that case was just people who'll contribute to this code in the future. Anecdotally, the person removed the Object.seal before the return because of performance reasons, based on a JSPerf test [3]. Interestingly, a JSPerf test with a proxy-based solution [4] might have convinced to do proxies instead of Object.seal. Take all these JSPerf micro benchmark games with two grains of salt; lots of them focus on premature optimisation. Also, seal and freeze are far more likely to see decent treat than proxies. But more importantly, I think you get too hung up on proxies as the proverbial hammer. Proxies are very much an expert feature. Using them for random micro abstractions is like shooting birds with a nuke. A language that makes that necessary would be a terrible language. All programmers messing with home-brewed proxies on a daily basis is a very scary vision, if you ask me. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
Nathan Wall wrote: Hey Allen, thanks for clarifying. What will happen to other Array methods which currently return Arrays? `filter` is the primary one that comes to mind. Will `uint32array.filter((v) = v != 0)` return a Uint32Array? (I think it should behave the same way `map` does.) I know I already said that, but I repeat: `map` transforms elements, `filter` just selects a subset. Therefore I am 100% for `filter` doing the same kind of collection as the receiver. Bit not necessarily for `map`. So I think, not, `filter` should not behave same as `map`. Additionally, what will happen with the return values of `slice`, `splice`, and `reverse`?.. not to mention `concat`, which I know is a much more complex beast. I think `filter` should behave the same as `slice`, `splice`, `reverse` and `concat`. They have clear rationale to use same kind of container. Nathan Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Are frozen Objects faster ?
If not, any particular reason these are not, being immutable and representable similar to a C struct ? If they could, any idea which engine is planning to optimize and when? Thanks and Best Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) -kg On Thu, Feb 14, 2013 at 9:48 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: If not, any particular reason these are not, being immutable and representable similar to a C struct ? If they could, any idea which engine is planning to optimize and when? Thanks and Best Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
On Thu, Feb 14, 2013 at 10:01 AM, Kevin Gadd kevin.g...@gmail.com wrote: Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) Likewise. And unlikely. Based on history, I suggest that the best way to get this situation fixed is benchmarks. Either create a new benchmark or a variation of an existing benchmark. For example, if someone created a variant of SunSpider in which all objects that don't need to not be frozen were frozen, and posted the measurements, that would help get everyone's attention. The situation might then improve rapidly. -kg On Thu, Feb 14, 2013 at 9:48 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: If not, any particular reason these are not, being immutable and representable similar to a C struct ? If they could, any idea which engine is planning to optimize and when? Thanks and Best Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Kevin Gadd wrote: Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) I, on the other hand, find it fortunate. Otherwise, some people would prematurely freeze objects to gain speed. It would be same deldisaster/del akwardness as v8 did with removing `delete` in favour of `= null`. Herby -kg ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
On Thu, Feb 14, 2013 at 10:09 AM, Herby Vojčík he...@mailbox.sk wrote: Kevin Gadd wrote: Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) I, on the other hand, find it fortunate. Otherwise, some people would prematurely freeze objects to gain speed. It would be same deldisaster/del akwardness as v8 did with removing `delete` in favour of `= null`. What are you referring to? What 'delete' was removed? Herby -kg __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
On 14 February 2013 19:01, Kevin Gadd kevin.g...@gmail.com wrote: The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features Well, regarding V8, there is now. :) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
On 14 February 2013 19:08, Mark S. Miller erig...@google.com wrote: Based on history, I suggest that the best way to get this situation fixed is benchmarks. Either create a new benchmark or a variation of an existing benchmark. For example, if someone created a variant of SunSpider in which all objects that don't need to not be frozen were frozen, and posted the measurements, that would help get everyone's attention. The situation might then improve rapidly. Gulp. Mark, you didn't just suggest using SunSpider as the basis for a future benchmark, did you? My eyes must have tricked me. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
Le 14/02/2013 18:11, Andreas Rossberg a écrit : On 13 February 2013 13:39, David Bruant bruan...@gmail.com wrote: Warning: In this post, I'll be diverging a bit from the main topic. Le 12/02/2013 14:29, Brendan Eich a écrit : Loss oread onlyf identity, extra allocations, and forwarding overhead remain problems. I'm doubtful loss of identity matters often enough to be a valid argument here. I'd be interested in being proved wrong, though. I understand the point about extra allocation. I'll talk about that below. The forwarding overhead can be made inexistent in the very case I've exposed because in the handler, the traps you care about are absent from the handler, so engines are free to optimize the [[Get]]friends as operations applied directly to the target. You're being vastly over-optimistic about the performance and the amount of optimisation that can realistically be expected for proxies. Proxies are inherently unstructured, higher-order, and effectful, which defeats most sufficiently simple static analyses. A compiler has to work much, much harder to get useful results. Don't expect anything anytime soon. var handler = {set: function(){throw new TypeError}} var p = new Proxy({a: 32}, handler); p.a; It's possible *at runtime* to notice that the handler of p doesn't have a get trap, optimize p.[[Get]] as target.[[Get]] and guard this optimization on handler modifications. Obviously, do that only if the code is hot. I feel it's not that much work than what JS engines do currently and the useful result is effectively getting rid of the forwarding overhead. Is this vastly over-optimistic? I've seen this in a previous experience on a Chrome extension where someone would seal an object as a form of documentation to express I need these properties to stay in the object. It looked like: function C(){ // play with |this| return Object.seal(this) } My point here is that people do want to protect their object integrity against untrusted parties which in that case was just people who'll contribute to this code in the future. Anecdotally, the person removed the Object.seal before the return because of performance reasons, based on a JSPerf test [3]. Interestingly, a JSPerf test with a proxy-based solution [4] might have convinced to do proxies instead of Object.seal. Take all these JSPerf micro benchmark games with two grains of salt; ... that's exactly what I said right after :-/ But that's a JSPerf test and it doesn't really measure the GC overhead of extra objects. JSPerf only measures one part of perf the story and its nice conclusion graph should be taken with a pinch of salt. lots of them focus on premature optimisation. I'm quite aware. I fear the Sphinx [1]. I wrote might have convinced to do proxies instead of Object.seal. I didn't say I agreed. and I actually don't. Also, seal and freeze are far more likely to see decent treat than proxies. Why so? But more importantly, I think you get too hung up on proxies as the proverbial hammer. Proxies are very much an expert feature. Using them for random micro abstractions is like shooting birds with a nuke. A language that makes that necessary would be a terrible language. All programmers messing with home-brewed proxies on a daily basis is a very scary vision, if you ask me. hmm... maybe. David [1] https://twitter.com/ubench_sphinx ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
It was just an example. Feel free to make an alternative and more informed suggestion ;). On Thu, Feb 14, 2013 at 10:15 AM, Andreas Rossberg rossb...@google.comwrote: On 14 February 2013 19:08, Mark S. Miller erig...@google.com wrote: Based on history, I suggest that the best way to get this situation fixed is benchmarks. Either create a new benchmark or a variation of an existing benchmark. For example, if someone created a variant of SunSpider in which all objects that don't need to not be frozen were frozen, and posted the measurements, that would help get everyone's attention. The situation might then improve rapidly. Gulp. Mark, you didn't just suggest using SunSpider as the basis for a future benchmark, did you? My eyes must have tricked me. /Andreas -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Le 14/02/2013 19:08, Mark S. Miller a écrit : On Thu, Feb 14, 2013 at 10:01 AM, Kevin Gadd kevin.g...@gmail.com mailto:kevin.g...@gmail.com wrote: Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) Likewise. And unlikely. Based on history, I suggest that the best way to get this situation fixed is benchmarks. Agreed 100% Either create a new benchmark or a variation of an existing benchmark. For example, if someone created a variant of SunSpider in which all objects that don't need to not be frozen were frozen, and posted the measurements, that would help get everyone's attention. The situation might then improve rapidly. Choice of the specific benchmark aside, this is a very good idea. This could also be applied to strict mode. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Mark S. Miller wrote: On Thu, Feb 14, 2013 at 10:09 AM, Herby Vojčík he...@mailbox.sk mailto:he...@mailbox.sk wrote: Kevin Gadd wrote: Frozen and sealed objects are both dramatically slower in most JS engines I've tested. In the ones where they're not dramatically slower they are never faster. The last time I asked on the mozilla and v8 bug trackers I was informed that there is no plan to optimize for these features and that the design of the respective JS engines would make such optimizations difficult anyway. (I find this extremely unfortunate.) I, on the other hand, find it fortunate. Otherwise, some people would prematurely freeze objects to gain speed. It would be same deldisaster/del akwardness as v8 did with removing `delete` in favour of `= null`. What are you referring to? What 'delete' was removed? I meant de facto. People wanting to remove property bar from foo do not write `delete foo.bar` anymore; they (at least some significant subset) have learned to write `foo.bar = null;` or `foo.bar = undefined;`. The reason is perf - `delete` deoptimized hidden classes. Herby -kg -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
On 14 February 2013 19:16, David Bruant bruan...@gmail.com wrote: Le 14/02/2013 18:11, Andreas Rossberg a écrit : You're being vastly over-optimistic about the performance and the amount of optimisation that can realistically be expected for proxies. Proxies are inherently unstructured, higher-order, and effectful, which defeats most sufficiently simple static analyses. A compiler has to work much, much harder to get useful results. Don't expect anything anytime soon. var handler = {set: function(){throw new TypeError}} var p = new Proxy({a: 32}, handler); p.a; It's possible *at runtime* to notice that the handler of p doesn't have a get trap, optimize p.[[Get]] as target.[[Get]] and guard this optimization on handler modifications. Obviously, do that only if the code is hot. I feel it's not that much work than what JS engines do currently and the useful result is effectively getting rid of the forwarding overhead. Is this vastly over-optimistic? Yes. Proxies hook into many different basic operations, and there are many special cases you could potentially optimise for each of them, many of which don't come for free. I very much doubt that any vendor currently has serious plans to go down that rathole instead of spending their energy elsewhere. Certainly not before it is clear how (and how much) proxies will actually be used in practice. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
On 14 February 2013 01:05, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Where do without, means replaced with set/getIntegrity traps and objects have explicit internal state whose value is one of normal/non-extensible/sealed/frozen (and possibly) fixed-inheritance between normal and non-extensible to freeze [[Prototype]]). [[SetIntegrity]] can increase the integrity level but not decrease it. The perf and invariant complexity concerns come from the fact that the sealed/frozen status of an object can only be inferred by inspecting all of its methods. Having an explicit state eliminates the need to do this inspection. It also simplifies the MOP by merging all of the extensible/sealed/frozen related MOP operations into only two ops. But, one way or another, these object state transitions must be accounted for in the MOP. For this to fly, implementation have to be able to expand their current 1 bit of of extensible state to at least 2 bits (3 would be better). Or perhaps not, I suppose we could just introduce the MOP level changes and a lazy implementation could continue to infer the state by examining all its methods. I still must be missing something. Why should the language be changed when the proposed change is equivalent anyway? Why is this an optimisation that the spec should worry about instead of the implementations? /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
Andreas Rossberg wrote: But more importantly, I think you get too hung up on proxies as the proverbial hammer. Proxies are very much an expert feature. Using them for random micro abstractions is like shooting birds with a nuke. A language that makes that necessary would be a terrible language. All programmers messing with home-brewed proxies on a daily basis is a very scary vision, if you ask me. This. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Andreas Rossberg wrote: On 14 February 2013 19:26, Herby Vojčíkhe...@mailbox.sk wrote: I meant de facto. People wanting to remove property bar from foo do not write `delete foo.bar` anymore; they (at least some significant subset) have learned to write `foo.bar = null;` or `foo.bar = undefined;`. The reason is perf - `delete` deoptimized hidden classes. And with ES6, those people will hopefully realise that for those cases, using a Map is a cleaner alternative anyway. No, it is another scenario. If an object is used as a Map, it should degrade to HashMap, it's ok. The problem is proliferation of `foo.bar = null` in normal code, where sometimes you want to remove some property (maybe it was an expando, or it is realy not needed any more in the actual phases of the lifecycle). In such cases, doing `delete` would degrade your optimized instance into a Hash. Thus, people do `foo.bar = null` even if what they want to do is `delete foo.bar`. /Andreas Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
This is definitely the case. Recent performance guidance from V8 developers strongly discouraged the use of 'delete' so I've gone to some lengths to avoid using it in my own code, mostly through design (trying to avoid scenarios that require the deletion of attributes). If this guidance isn't accurate anymore, I certainly never heard about it. Then again engine developers have said that they intentionally avoid publishing performance guidance since people continue to follow it after it becomes outdated - so I guess this is just support for that policy. :/ Anyway! I spent an hour or so building a simplified real-world benchmark for Object.freeze, by modifying a HTML5 game port to use Object.freeze at construction time for its immutable structured objects. These objects are basically simple tuples of integers/floats that are frequently constructed and passed around - think a Vector2 or Point data structure, etc. This file has detailed timings from the latest versions of Chrome Canary and Firefox Nightly with the Object.freeze call disabled and enabled, respectively, along with a URL you can hit to run it yourself: https://dl.dropbox.com/u/1643240/freeze%20timings.txt I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). So, I guess you could start using freeze in applications now if your users are all on latest FF/Chrome, and hope that in the future it will actually make you faster. Feel free to let me know if you have any questions (though if they're questions about the benchmark, maybe don't spam es-discuss with them :) ) -kg On Thu, Feb 14, 2013 at 11:56 AM, Herby Vojčík he...@mailbox.sk wrote: Andreas Rossberg wrote: On 14 February 2013 19:26, Herby Vojčíkhe...@mailbox.sk wrote: I meant de facto. People wanting to remove property bar from foo do not write `delete foo.bar` anymore; they (at least some significant subset) have learned to write `foo.bar = null;` or `foo.bar = undefined;`. The reason is perf - `delete` deoptimized hidden classes. And with ES6, those people will hopefully realise that for those cases, using a Map is a cleaner alternative anyway. No, it is another scenario. If an object is used as a Map, it should degrade to HashMap, it's ok. The problem is proliferation of `foo.bar = null` in normal code, where sometimes you want to remove some property (maybe it was an expando, or it is realy not needed any more in the actual phases of the lifecycle). In such cases, doing `delete` would degrade your optimized instance into a Hash. Thus, people do `foo.bar = null` even if what they want to do is `delete foo.bar`. /Andreas Herby ___ 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
Re: Are frozen Objects faster ?
On 14 February 2013 20:56, Herby Vojčík he...@mailbox.sk wrote: The problem is proliferation of `foo.bar = null` in normal code, where sometimes you want to remove some property (maybe it was an expando, or it is realy not needed any more in the actual phases of the lifecycle). In such cases, doing `delete` would degrade your optimized instance into a Hash. Thus, people do `foo.bar = null` even if what they want to do is `delete foo.bar`. By definition, if you want to delete it, it's not a normal property. In most languages, you couldn't even do that. The reason that you can in JavaScript is mostly historic. (And fortunately, I don't see a proliferation of this in practice.) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
On 14 February 2013 21:12, Kevin Gadd kevin.g...@gmail.com wrote: I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). Thanks for doing the benchmark, very interesting! That freeze bottleneck will hopefully vanish in the foreseeable future. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
the `delete obj.property` changes the shape of the object, right? so I think is more a problem of devs using objects as trash bin but this is the opposite scenario of a frozen object. I understand ES5 descriptors are an overhead during an object lifecycle but I think a mechanism to make frozen object that fast would be a win while we wait for better options on statically defined types. Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Will this cost more than now at freeze() time? I understand this might be undesired but think about libraries or modules that do not want to be extended, would like to be as fast as possible, and are loaded once and never again. Thanks for all thoughts and info already provided, also agreed on some bench. I usually do that on jsPerf 'cause I don't know how to reach those bigger, widely tested, one. Any hint here appreciated. On Thu, Feb 14, 2013 at 12:24 PM, Andreas Rossberg rossb...@google.comwrote: On 14 February 2013 21:12, Kevin Gadd kevin.g...@gmail.com wrote: I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). Thanks for doing the benchmark, very interesting! That freeze bottleneck will hopefully vanish in the foreseeable future. /Andreas ___ 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
Re: Are frozen Objects faster ?
On 14 February 2013 21:36, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Frozenness is largely irrelevant for typed arrays, since all array accesses are defined by a magic nameless getter/setter pair per the WebIDL spec. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
One more thought ... the best scenario **ever** would be the ability to define a frozen prototype and create already fixed shaped instance at runtime. I think Object.freeze() semantic is not the right one to do this, but I am dreaming about something like this: var MyStaticShapeConstructor = Object.createStaticConstructor( inheritFrom, // either null or actually not extremely important descriptors // descriptors we know ); var instance = new MyStaticShapeConstructor; We might discuss if the constructor property in descriptors should have a handy, exceptional, treatment (ie invoked with arguments) { constructor: { value: function (a, b, c) { // invoked when new MyStaticShapeConstructor(1,2,3) } } } or simply encourage the usage of o.init(arg1, ..., argN); I know this is way too much magic behind the scene but it would be straight forward from different points of view, at least for JS users, IMHO, and really easy to polyfill. Thoughts on this would be much appreciated, thanks. Apologies if already discussed and I have missed that thread. br On Thu, Feb 14, 2013 at 12:36 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: the `delete obj.property` changes the shape of the object, right? so I think is more a problem of devs using objects as trash bin but this is the opposite scenario of a frozen object. I understand ES5 descriptors are an overhead during an object lifecycle but I think a mechanism to make frozen object that fast would be a win while we wait for better options on statically defined types. Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Will this cost more than now at freeze() time? I understand this might be undesired but think about libraries or modules that do not want to be extended, would like to be as fast as possible, and are loaded once and never again. Thanks for all thoughts and info already provided, also agreed on some bench. I usually do that on jsPerf 'cause I don't know how to reach those bigger, widely tested, one. Any hint here appreciated. On Thu, Feb 14, 2013 at 12:24 PM, Andreas Rossberg rossb...@google.comwrote: On 14 February 2013 21:12, Kevin Gadd kevin.g...@gmail.com wrote: I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). Thanks for doing the benchmark, very interesting! That freeze bottleneck will hopefully vanish in the foreseeable future. /Andreas ___ 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
Re: Are frozen Objects faster ?
I wodner how come Firefox behaves like that then but I don't have tests to compare any difference between these two. I will write some, thanks On Thu, Feb 14, 2013 at 12:48 PM, Andreas Rossberg rossb...@google.comwrote: On 14 February 2013 21:36, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Frozenness is largely irrelevant for typed arrays, since all array accesses are defined by a magic nameless getter/setter pair per the WebIDL spec. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Are frozen Objects faster ?
Ideally the JIT would, at runtime, just identify the pattern where your constructor ends with an Object.freeze(this) call, and turn it into the equivalent of an immutable, pass-by-value packed struct. IIRC v8 and SpiderMonkey are both able to do some of this already based on looking at your constructor and using shape information... -kg On Thu, Feb 14, 2013 at 12:49 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: One more thought ... the best scenario **ever** would be the ability to define a frozen prototype and create already fixed shaped instance at runtime. I think Object.freeze() semantic is not the right one to do this, but I am dreaming about something like this: var MyStaticShapeConstructor = Object.createStaticConstructor( inheritFrom, // either null or actually not extremely important descriptors // descriptors we know ); var instance = new MyStaticShapeConstructor; We might discuss if the constructor property in descriptors should have a handy, exceptional, treatment (ie invoked with arguments) { constructor: { value: function (a, b, c) { // invoked when new MyStaticShapeConstructor(1,2,3) } } } or simply encourage the usage of o.init(arg1, ..., argN); I know this is way too much magic behind the scene but it would be straight forward from different points of view, at least for JS users, IMHO, and really easy to polyfill. Thoughts on this would be much appreciated, thanks. Apologies if already discussed and I have missed that thread. br On Thu, Feb 14, 2013 at 12:36 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: the `delete obj.property` changes the shape of the object, right? so I think is more a problem of devs using objects as trash bin but this is the opposite scenario of a frozen object. I understand ES5 descriptors are an overhead during an object lifecycle but I think a mechanism to make frozen object that fast would be a win while we wait for better options on statically defined types. Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Will this cost more than now at freeze() time? I understand this might be undesired but think about libraries or modules that do not want to be extended, would like to be as fast as possible, and are loaded once and never again. Thanks for all thoughts and info already provided, also agreed on some bench. I usually do that on jsPerf 'cause I don't know how to reach those bigger, widely tested, one. Any hint here appreciated. On Thu, Feb 14, 2013 at 12:24 PM, Andreas Rossberg rossb...@google.com wrote: On 14 February 2013 21:12, Kevin Gadd kevin.g...@gmail.com wrote: I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). Thanks for doing the benchmark, very interesting! That freeze bottleneck will hopefully vanish in the foreseeable future. /Andreas ___ 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
Re: Are frozen Objects faster ?
that is assuming nobody ever call the constructor without new keyword and no inheritance is involved, since the sub constructor would be trapped behind the parent. That would be even more magic ... I kinda like it, not sure is explicit enough though ... but yeah, if freeze(this) would do that, it would be awesome! On Thu, Feb 14, 2013 at 12:50 PM, Kevin Gadd kevin.g...@gmail.com wrote: Ideally the JIT would, at runtime, just identify the pattern where your constructor ends with an Object.freeze(this) call, and turn it into the equivalent of an immutable, pass-by-value packed struct. IIRC v8 and SpiderMonkey are both able to do some of this already based on looking at your constructor and using shape information... -kg On Thu, Feb 14, 2013 at 12:49 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: One more thought ... the best scenario **ever** would be the ability to define a frozen prototype and create already fixed shaped instance at runtime. I think Object.freeze() semantic is not the right one to do this, but I am dreaming about something like this: var MyStaticShapeConstructor = Object.createStaticConstructor( inheritFrom, // either null or actually not extremely important descriptors // descriptors we know ); var instance = new MyStaticShapeConstructor; We might discuss if the constructor property in descriptors should have a handy, exceptional, treatment (ie invoked with arguments) { constructor: { value: function (a, b, c) { // invoked when new MyStaticShapeConstructor(1,2,3) } } } or simply encourage the usage of o.init(arg1, ..., argN); I know this is way too much magic behind the scene but it would be straight forward from different points of view, at least for JS users, IMHO, and really easy to polyfill. Thoughts on this would be much appreciated, thanks. Apologies if already discussed and I have missed that thread. br On Thu, Feb 14, 2013 at 12:36 PM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: the `delete obj.property` changes the shape of the object, right? so I think is more a problem of devs using objects as trash bin but this is the opposite scenario of a frozen object. I understand ES5 descriptors are an overhead during an object lifecycle but I think a mechanism to make frozen object that fast would be a win while we wait for better options on statically defined types. Binary Arrays are indeed frozen objects, at least in Firefox, and ultra fast: Object.isFrozen(new Float32Array()) // true in Firefox Since these are ultra fast in Chrome too but not frozen, I believe there is already a way to speed up typed stuff (didn't check how it's done though) so I wonder how come Object.freeze() is not taking similar approach typizing behind the scene the object improving all static properties getters (probably dropping those getters where possible unless defined as such) Will this cost more than now at freeze() time? I understand this might be undesired but think about libraries or modules that do not want to be extended, would like to be as fast as possible, and are loaded once and never again. Thanks for all thoughts and info already provided, also agreed on some bench. I usually do that on jsPerf 'cause I don't know how to reach those bigger, widely tested, one. Any hint here appreciated. On Thu, Feb 14, 2013 at 12:24 PM, Andreas Rossberg rossb...@google.com wrote: On 14 February 2013 21:12, Kevin Gadd kevin.g...@gmail.com wrote: I'm pleased to report that Object.freeze does not seem to cause an enormous performance hit in v8 anymore. Hooray! Unfortunately, the call to Object.freeze itself shows up as a bottleneck in V8 profiles, and the 'freeze enabled' version is slower in both versions (though at least only slightly slower). Thanks for doing the benchmark, very interesting! That freeze bottleneck will hopefully vanish in the foreseeable future. /Andreas ___ 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
Re: A case for removing the seal/freeze/isSealed/isFrozen traps
Andreas Rossberg wrote: On 14 February 2013 19:16, David Bruantbruan...@gmail.com wrote: Le 14/02/2013 18:11, Andreas Rossberg a écrit : You're being vastly over-optimistic about the performance and the amount of optimisation that can realistically be expected for proxies. Proxies are inherently unstructured, higher-order, and effectful, which defeats most sufficiently simple static analyses. A compiler has to work much, much harder to get useful results. Don't expect anything anytime soon. var handler = {set: function(){throw new TypeError}} var p = new Proxy({a: 32}, handler); p.a; It's possible *at runtime* to notice that the handler of p doesn't have a get trap, optimize p.[[Get]] as target.[[Get]] and guard this optimization on handler modifications. Obviously, do that only if the code is hot. I feel it's not that much work than what JS engines do currently and the useful result is effectively getting rid of the forwarding overhead. Is this vastly over-optimistic? Yes. Proxies hook into many different basic operations, and there are many special cases you could potentially optimise for each of them, many of which don't come for free. I very much doubt that any vendor currently has serious plans to go down that rathole instead of spending their energy elsewhere. Certainly not before it is clear how (and how much) proxies will actually be used in practice. You're right in general, and we have not optimized, e.g. inlining scripted trap calls. We did do something special for our new DOM bindings I wanted to pass along, in case anyone is interested: https://bugzilla.mozilla.org/show_bug.cgi?id=769911 Thanks to bz for the link. This is yet another inline cache specialization for expandos on nodelists. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array subclassing, .map and iterables (Re: Jan 30 TC39 Meeting Notes)
Andreas Rossberg wrote: I'd say that either we properly clean up the Array hierarchy, or we leave it alone. A half-baked solution that only applies to typed arrays, and divorces them from the Array hierarchy, seems less attractive than just doing the naive thing, i.e., TypedArray Array. Agree with that, and I'll go further: we should leave alone what's already shipped and in use for a long time. TypedArray Array sounds good to me. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss