ArrayClass should imply @@isConcatSpreadable

Boris Zbarsky bzbarsky at MIT.EDU
Tue Oct 29 00:07:16 PDT 2013


On 10/28/13 8:50 PM, Allen Wirfs-Brock wrote:
> So what's so onerous about returning a fresh array from the getter each time it was called.  If it was implemented in Es6, it would just be:
>      return Array.from(internal_compy);

Implementing this is pretty easy, for sure.

The questions are:

1)  What the object-identity expectations of callers are.
2)  Whether this can cause nasty O(N^2) behavior when people loop over 
the property's value in a naive way.  Mostly an issue if the list can be 
long, so not a problem for the gamepad API but could be a problem for 
other use cases.

> Proxies aren't cheap. Unless these arrays tend to be quite large, I wouldn't be surprised if the overhead of using a Proxy for this useless ended up being higher than the cost of making fresh arrays.

Maybe.   Measuring in Firefox [1] a get on a proxy seems to be in the 
~100ns range for me, while duplicating a small array (3 entries) via 
slice.call() seems to be about 300ns (mostly the call overhead). 
Duplicating an array with ~100 entries takes closer to 2000ns, just to 
see the scaling here.

-Boris

[1] Testcase:

<!DOCTYPE html>
<body>
   <pre><script>
     var count = 4000000;
     var arr = [1, 2, 3];
     var slice = Array.prototype.slice;
     var proxy = new Proxy(arr, {});
     var sideEffect;
     var i;

     var start = new Date;
     for (i = 0; i < count; ++i) {
     }
     var stop = new Date;
     document.writeln("Empty loop: " + (stop - start) / count * 1e6 + "ns");

     var start = new Date;
     for (var i = 0; i < count; ++i) {
       sideEffect = arr[0];
     }
     var stop = new Date;
     document.writeln("Normal array get: " + (stop - start) / count * 
1e6 + "ns");

     var start = new Date;
     for (var i = 0; i < count; ++i) {
       sideEffect = proxy[0];
     }
     var stop = new Date;
     document.writeln("Proxy get: " + (stop - start) / count * 1e6 + "ns");

     var start = new Date;
     for (var i = 0; i < count; ++i) {
       sideEffect = slice.call(arr);
     }
     var stop = new Date;
     document.writeln("Array creation, length " + arr.length +": " + 
(stop - start) / count * 1e6 + "ns");

     arr = arr.concat(arr);
     arr = arr.concat(arr);
     arr = arr.concat(arr);
     arr = arr.concat(arr);
     arr = arr.concat(arr);
     var start = new Date;
     for (var i = 0; i < count; ++i) {
       sideEffect = slice.call(arr);
     }
     var stop = new Date;
     document.writeln("Array creation, length " + arr.length +": " + 
(stop - start) / count * 1e6 + "ns");
   </script>



More information about the es-discuss mailing list