How does javascript array work when clicking new elements?

I tested this code in Chrome / Firefox:

console.time('simple push'); var arr0 = []; for(var i =0; i < 1000000; i++){ arr0.push(i); } console.timeEnd('simple push'); console.time('set length and push'); var arr1 = []; arr1.length=1000000; for(var j =0; j < 1000000; j++){ arr1[j]=j; } console.timeEnd('set length and push'); console.time('new Array push'); var arr2 = new Array(1000000); for(var k =0; k < 1000000; k++){ arr2[k]=k; } console.timeEnd('new Array push'); 

Chrome 13 Result

simple push: 59ms
set length and push: 192ms
new array: 187 ms

Firefox 4 Result

simple push: 76ms
set the length and press: 44 ms
new array: 40 ms

My doubts

So the new Array operation is by far the slowest, but I want to know why?
Why does setting length behave differently in Chrome and Firefox, does pre-allocated memory seem to work poorly in Chrome?

Update

I updated the results of Chrome and FF.

+7
source share
2 answers

Why is the new array (N) the slowest?

 console.log(arr0.length); console.log(arr1.length); console.log(arr2.length); 1000000 1000000 2000000 
+6
source

As you already know, your test codes were wrong. Here is an example jsperf test that uses assignment in all methods.

The speed is the same for all of them in Firefox 6 (~ 50,000 op / s). However, in Chrome 13, setting the length of the array in advance leads to a huge increase in speed (~ 80,000 op / s versus ~ 400,000 op / s). To find the reason for this, you would need to take a look at the source code of the Chrome JavaScript engine.

You asked what happens on .push() and new Array . It is necessary to describe the specification:

15.4.2.2 new array (len)

The internal [[Prototype]] property for the newly created object is set to the original Array prototype object, one that is the initial value of Array.prototype ( 15.4.3. 1). The internal [[Class]] property for the newly created object is " Array ". The internal [[Extensible]] property of the newly created object is true .

If the argument of len is Number and ToUint32(len) is equal to len, then the length property for the newly created object is set to ToUint32(len) . If the argument of len is Number and ToUint32(len) not equal to len, a RangeError exception is thrown .

If len is not a number, then the length property of the newly created object is set to 1, and the 0 property of the newly created object is set to len with the attributes {[[Writable]]: true, [[Enumerable]]: true, [[Configurable] ]: true} ..

15.4.4.7 Array.prototype.push ([item1 [, item2 [, ...]]])

Arguments are added to the end of the array in the order in which they are displayed. The new array length is returned as a result of the call.

When the push method is called with zero or more arguments item1, item2, etc., the following steps are performed:

  • Let O be the result of calling ToObject, passing this value as an argument.
  • Let lenVal be the result of calling the [[Get]] O internal method with the argument " length ".
  • Let n be ToUint32 (lenVal).
  • Let the elements be an internal list, the elements of which are in order from left to right, the arguments that were passed to this function call.
  • Repeat while items are not empty
    • Remove the first element from the elements and let E be the value of the element.
    • Call the internal method O [[Put]] with arguments ToString (n), E, ​​and true .
    • Increase n by 1.
  • Call the internal method O [[Put]] with arguments length ", n and true .
  • Returns n.

However, the implementation may be different. As you saw from the difference in Firefox and Chrome, Chrome seems to internally optimize the structure of the array.

0
source

All Articles