13

What are the downsides to doing:

var myArray = [];
myArray[myArray.length] = val1;
myArray[myArray.length] = val2;

instead of:

var myArray = [];
myArray.push(val1);
myArray.push(val2);

I'm sure the push method is much more "acceptable", but are there any differences in functionality?

mowwwalker
  • 16,634
  • 25
  • 104
  • 157

7 Answers7

6

push is way faster, almost 300% faster.

Proof: http://jsperf.com/push-vs-length-test

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
  • 2
    i ran the test twice (firefox) and in both case push is slower (about 6%). However in Chrome is different (push is 50% fast). Also Firefox is fast than Chrome (for this test) using the Latest firefox and chrome. – magallanes Aug 30 '11 at 18:49
  • Odd. Seems like for most modern browsers (Chrome >= 19), length is way faster. See the browserscope box on the jsperf page. – Timothy Gu Nov 11 '14 at 04:40
  • @magallanes Chrome 19 seems to boost the performance of the length method a lot, so much it is now over 1.5 times faster than `push()` on small arrays. – Timothy Gu Nov 11 '14 at 04:44
  • Agree with others here -- this seems to have changed over time, and depends on the browser. Currently (Feb 2016) it seems like `array[array.length] =` is mostly pretty close to the same (Firefox) or faster (Chrome, Safari). I'm on a Mac so I can't test Windows-specific browsers accurately. – Benjamin Robinson Feb 25 '16 at 19:34
5

Since arrays in JavaScript do not have holes the functionality of those two methods is equal. And yes, using .push() is much cleaner (and shorter).

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 1
    Theoretically, yes. But looking at the jsperf made by @AlienWebguy and @naveen `.push()` is much slower. But in any case this kind of microoptimization probably doesn't worth much in real life. – Timothy Gu Nov 11 '14 at 04:42
4

I've generally thought length assignment was faster. Just found Index vs. push performance which backs that up; for my Chrome 14 browser anyway, over a single test run. However there is not much in it in Chrome.

andyb
  • 43,435
  • 12
  • 121
  • 150
  • What version of Chrome? Are you saying that push (the 2nd test) is slower than the 1st or 3rd test? – kzh Sep 12 '11 at 14:43
4

There seems to be discrepancy on which test is faster among the varying JavaScript engines. The differences in speed may be negligible (unless an unholy amount of pushes are needed). In that case, the prudent developer should always err on the side of readability. In this case, in my opinion and the opinion of @TheifMaster is that [].push() is cleaner and it is easier to read. Maintenance of code is the most expensive part of coding.

Community
  • 1
  • 1
kzh
  • 19,810
  • 13
  • 73
  • 97
3

As I tested, the first way is faster, I'm not sure why, keep researching. Also the ECMA doesn't mentioned which one is better, I think it is depending on how the browser vendor implements this.

var b = new Array();
var bd1 = new Date().getTime();
for(var i =0;i<1000000; i++){
    b[b.length] = i;
};

alert(new Date().getTime()- bd1);

var a = new Array();
var ad1 = new Date().getTime();
for(var i =0;i<1000000; i++){
    a.push(i);
};

alert(new Date().getTime()- ad1);
ib.
  • 27,830
  • 11
  • 80
  • 100
Howard
  • 3,638
  • 4
  • 32
  • 39
  • Are you saying that `myArray[myArray.length] = val1;` is faster? What browser are you using? – kzh Sep 12 '11 at 14:42
  • The result that: the first case is much faster in Chrome and Firefox, but litter faster in IE9, I don't have a lower version of IE; so in all, it's faster in these browsers. – Howard Sep 13 '11 at 00:52
2

In JS there are 3 different ways you can add an element to the end of an array. All three have their different use cases.

1) a.push(v), a.push(v1,v2,v3), a.push(...[1,2,3,4]), a.push(..."test")

Push is not a very well thought function in JS. It returns the length of the resulting array. How silly. So you can never chain push() in functional programming unless you want to return the length at the very end. It should have returned a reference to the object it's called upon. I mean then it would still be possible to get the length if needed like a.push(..."idiot").length. Forget about push if you have intentions to do something functional.

2) a[a.length] = "something"

This is the biggest rival of a.push("something"). People fight over this. To me the only two differences are that

  • This one returns the value added to the end of the array
  • Only accepts single value. It's not as clever as push.

You shall use it if the returned value is of use to you.

3. a.concat(v), a.concat(v1,v2,v3), a.concat(...[1,2,3,4]), a.concat([1,2,3,4])

Concat is unbelievably handy. You can use it exactly like push. If you pass the arguments in array it will spread them to the end of the array it's called upon. If you pass them as separate arguments it will still do the same like a = a.concat([1,2,3],4,5,6); //returns [1, 2, 3, 4, 5, 6] However don't do this.. not so reliable. It's better to pass all arguments in an array literal.

Best thing with concat is it will return a reference to the resulting array. So it's perfect to use it in functional programming and chaining.

Array.prototype.concat() is my preference.

4) A new push() proposal

Actually one other thing you can do is to overwrite the Array.prototype.push() function like;

Array.prototype.push = function(...args) {
                         return args.reduce(function(p,c) {
                                              p[p.length] = c;
                                              return p
                                            }, this)
                       };

so that it perfectly returns a reference to the array it's called upon.

Redu
  • 25,060
  • 6
  • 56
  • 76
  • 2
    `a` can be returned with the [Comma operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator#Processing_and_then_returning) `(a.push(v), a)` or `(a[a.length] = v, a)` – Slai Sep 23 '17 at 01:04
0

I have an updated benchmark here: jsbench.me Feel free to check which is faster for your current engine. arr[arr.length] was about 40% faster than arr.push() on Chromium 86.