3

I have been wondering recently.

I have in the past used [].slice.call or [].forEach.call .... etc I thought doing it this way was great because it makes it easy to turn something array like, into an array easily.

However, then I started thinking about it and it would be better to do something like this: Array.prototype.slice.call or Array.prototype.forEach.call instead.

Am I correct in thinking that this has much better performance for the following reasons:

  1. [].slice.call would create a blank array, then access the arrays prototype and would need to be garbage collected later on.
  2. Array.prototype.slice.call would call the Array prototype method directly, and would not first create a blank array and then traverse the prototype tree.

Is there anything I have missed? also is there anything I am missing, such as a reason why in some cases [] would be better than Array.prototype?

9
  • Two standard replies. First, this is not your bottleneck. Second, time it; I have no idea which is faster. Commented May 14, 2014 at 9:06
  • 2
    I suspect the main reason some people like [] is just because it's shorter. Commented May 14, 2014 at 9:17
  • @Barmar That was why I liked it in the first place :) Commented May 14, 2014 at 9:18
  • 1
    I would not use [].slice.call but e.g. store the Array.prototype.slice in a local var. The reason why I wouldn't use [].slice.call is because it creates a object that is never used, even though it most likely would not have noticeable performance impacts. Commented May 14, 2014 at 9:22
  • 1
    @JulienFouilhé Array.prototype.slice.call( arguments-or-whatever ) is a common pattern to convert array-like objects (as arguments on functions), to "true" Arrays. Commented May 14, 2014 at 9:25

1 Answer 1

4

Please refer to existing benchmarks

Like this one on jsperf.com I found typing "`[].slice performance" on google.

Revision 15 of the same benchmark also provides a wide variety of approaches, while revision 12 was also interesting for me.

What code to use

As @Barmar pointed out on comments, [].slice.call is shorter than Array.prototype.slice.call, so it's pretty common to see the former.

As @t.niese pointed out on comments, [].slice.call creates a object that is never used, even though it most likely would not have noticeable performance impacts.

IMHO, if worried about performance, I prefer creating a shortcut with bind on an outer scope and then use it, instead shortcuting Array.prototype.slice.call with [].slice.call:

var slice = Function.prototype.call.bind( Array.prototype.slice );

// and then just

function doSomething( ){
    slice( arguments );
    slice( arguments, 1, -1 );
}

slice( whatever );
slice( whatever, 0, 3 );

// and so on

Conclusions

Definitely, as seen on benchmarks, performance is not the same.

When performance really matters, just benchmark your code to optimize it according to your requeriments.

When performance does not matter enought to worry about a small improvement like this one, it's a code style related decision, so pick your personal preference or follow the code style guide of the project you are working at.

Side note

@Barmar posted a link on comments about Premature Optimization really interesting too.

Sign up to request clarification or add additional context in comments.

10 Comments

Thats a strange test: _slcall = [].slice.call. This will result in an undefined is not a function error for the _slcall(items); test
@t.niese Yeah, revision 15 is a bit crazy. Revision 1 is just fine to feed OP's curiosity.
@laconbass I knew that Array.prototype should be quicker and have come across the jsperf before. Just wanted to know if there was something blindingly obvious I have overlooked or just didnt know. I want to be a javascript developer so I want to know everything :)
If a var slice = Array.prototype.slice; slice.call(items); is faster/slower then your bind example (which also looks nice), mainly depends on the js engine itself. But anyway if using one of them results in a bottleneck then there is most likely a bigger problem with the program/workflow itself (after converting the array-like to an array object the data is also used for something and this step normally takes much more time then the converting step).
@laconbass Thanks for the Answer :) it did bring about some good discussion, would be great for anyone else who happens to find the question!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.