unj2
unj2

Reputation: 53481

JavaScript's Statement Performance Questions

Can you guys help me determine the performance difference of each of these statements? Which one would you use?

  1. Making a new Array using

    - var new_list = new Array();  //or
    - var new_list = [];
    
  2. Appending element using

    - push('a')
    - new_list[i]; (if i know the length)
    
  3. Ternary operator or if() {} else (){}

  4. Trying to make isodd function, which is faster

    (! (is_even)) or (x%2!=0)
    
  5. forEach() or normal iteration

one more

  1. a= b = 3; or b=3; a=b;

[edit: I'm making a Math Library. So any performance hacks discussions are also welcome :) ]

Thanks for your help.

Upvotes: 6

Views: 356

Answers (6)

olliej
olliej

Reputation: 36783

Performance characteristics for all browser (especially at the level of individual library functions) can vary dramatically, so it's difficult to give meaningful really meaningful answers to these questions.

Anyhoo, just looking at the fast js engines (so Nitro, TraceMonkey, and V8)

  1. [ ] will be faster than new Array -- new Array turns into the following logic

    1. cons = lookup property "Array", if it can't be found, throw an exception
    2. Check to see if cons can be used as a constructor, if not: throw an exception
    3. thisVal = runtime creates a new object directly
    4. res = result of calling cons passing thisVal as the value for this -- which requires logic to distinguish JS functions from standard runtime functions (assuming standard runtime functions aren't implemented in JS, which is the normal case). In this case Array is a native constructor which will create and return a new runtime array object.
    5. if res is undefined or null then the final result is thisVal otherwise the final result is res. In the case of calling Array a new array object will be returned and thisVal will be thrown away

    [ ] just tells the JS engine to directly create a new runtime array object immediately with no additional logic. This means new Array has a large amount of additional (not very cheap) logic, and performs and extra unnecessary object allocation.

  2. newlist[newlist.length] = ... is faster (esp. if newlist is not a sparse array), but push is sufficiently common for me to expect engine developers to put quite a bit of effort into improving performance so this could change in time.

  3. If you have a tight enough loop there may be a very slight win to the ternary operator, but arguably that's an engine flaw in the trival case of a = b ? c : d vs if (b) a = c; else a = d

  4. Just the function call overhead alone will dwarf the cost of more or less any JS operator, at least in the sane cases (eg. you're performing arithmetic on numbers rather than objects)

  5. The foreach syntax isn't yet standardised but its final performane will depend on a large number of details; Often JS semantics result in efficient looking statements being less efficient -- eg. for (var i in array) ... is vastly slower than for (var i = 0; i < array.length; i++) ... as the JS semantics require in enumeration to build up a list of all properties on the object (including the prototype chain), and then checking to make sure that each property is still on the object before sending it through the loop. Oh, and the properties need to be converted from integers (in the array case anyway) into strings, which costs time and memory.

Upvotes: 4

unj2
unj2

Reputation: 53481

This page says push is slower. http://dev.opera.com/articles/view/efficient-javascript/?page=2

Upvotes: 0

Drahcir
Drahcir

Reputation: 981

I've always assumed that since (x&1) is a bitwise operation, it would be the fastest way to check for even/odd numbers, rather than checking for the remainder of the number.

Upvotes: 5

Alconja
Alconja

Reputation: 14873

As other posters suggest, I think doing some rough benchmarking is your best bet... however, I'd also note that you'll probably get very different results from different browsers, since I'm sure most of the questions you're asking come down to specific internal implementation of the language constructs rather than the language itself.

Upvotes: 1

cgp
cgp

Reputation: 41381

  1. Both are native constructors probably no difference.
  2. push is faster, it maps directly to native, where as [] is evaluative
  3. Probably not much of a difference, but technically, they don't do the same thing, so it's not apples to apples
  4. x%2, skips the function call which is relatively slow
  5. I've heard, though can't find the link at the moment, that iteration is faster than the foreach, which was surprising to me.

Edit: On #5, I believe the reason is related to this, in that foreach is ordered forward, which requires the incrementor to count forward, whereas for loops are ever so infinitesimally faster when they are run backward:

for(var i=a.length;i>-1;i--) {
    // do whatever
}

the above is slightly faster than:

for(var i=0;i<a.length;i++) {
    // do whatever
}

Upvotes: 3

Seb
Seb

Reputation: 25147

I'd suggest you code a simple script like:

for(var i = 0; i < 1000; i++){
  // Test your code here.
}

You can benchmark whatever you want that way, possibly adding timing functions before and after the for statement to be more accurate.

Of course you'll need to tweak the upper limit (1000 in this example) depending on the nature of your operations - some will require more iterations, others less.

Upvotes: 4

Related Questions