10

I've heard alot of people saying that accessing the arguments object is expensive. (example: Why was the arguments.callee.caller property deprecated in JavaScript?)

Btw what exactly does that statement mean at all? isn't accessing the arguments object simply a simple property lookup? what exactly is the big deal?

Community
  • 1
  • 1
Pacerier
  • 86,231
  • 106
  • 366
  • 634

2 Answers2

14

The big deal is at least twofold:

1) Accessing the arguments object has to create an arguments object. In particular, modern JS engines don't actually create a new object for the arguments every time you call a function. They pass the arguments on the stack, or even in machine registers. As soon as you touch arguments, though, they have to create an actual object. This is not necessarily cheap.

2) Once you touch the arguments object, various optimizations that JS engines can otherwise perform (e.g. detecting cases in which you never assign to an argument and optimizing that common case) go out the window. Every access to the function arguments, not just ones through arguments becomes much slower because the engine has to deal with the fact that you might have messed with the arguments via arguments.

Boris Zbarsky
  • 34,758
  • 5
  • 52
  • 55
  • Good explanation - I figured it was something like that. – Tamzin Blake May 27 '11 at 03:30
  • Wow, I'm really impressed with this excellent answer. Have you worked on any JS engine? – Sebastián Grignoli May 27 '11 at 03:34
  • @Boris Zbarsky . is it true to say that if we do read-only stuff like get arguments.length then the overhead is simply creating a new arguments object and the various optimizations won't be affected? – Pacerier May 27 '11 at 04:12
  • @Pacerier I don't know. I wouldn't be surprised if it depends on the JS engine.... In Spidermonkey, for example, `arguments.length` specifically is special-cased to not even create a new object; it's compiled to a bytecode that just directly gets the current function's argument count. – Boris Zbarsky May 27 '11 at 05:24
  • 2
    Pacerier, generally once an `arguments` object's created you're going to go slower for various operations, but there are some (engine-specific) exceptions. In Mozilla browsers neither `arguments.length` nor `arguments[#]` where `#` is a numeric literal will induce creation of an `arguments` object, and even if one's created these two tricks will generally be pretty fast. And going forward a couple more tricks are being implemented in Mozilla to avoid creating `arguments` in even more cases. But the exact details are very engine-specific. Ideally avoid using `arguments` as much as you can. – Jeff Walden May 27 '11 at 05:34
  • 1
    For completeness, `arguments.callee` won't induce creation of the `arguments` object, either (at least assuming you don't assign to it, that is). – Jeff Walden May 27 '11 at 05:35
  • @Jeff Walden. what if the string "arguments.callee" is not found. I mean what if we do **var args=arguments; args.callee** – Pacerier May 27 '11 at 06:42
  • @Jeff Walden. what if the string "arguments.callee" is not found. I mean what if we do var args=arguments; args.callee – Pacerier May 31 '11 at 03:07
  • `args.callee` (where `args` is not the exact token `arguments`) currently induces early creation of `arguments`. We're working on optimizations which might make that not do so in the future, but it's possible they might not. I doubt we'll expend any extra effort on optimizing that case, if it doesn't fall out naturally. Note that in ECMAScript 5's strict mode, `arguments.callee` is not a reference to the enclosing function (rather, it's a property which throws a `TypeError` when used in any way). – Jeff Walden Jun 23 '11 at 22:45
0

I have also never heard a serious explanation for why accessing the arguments object is expensive. However, this site: http://www.playmycode.com/blog/2011/03/simple-yet-effective-javascript-optimisations/ notes that arguments is not really an array and is less efficient than accessing an array. The above linked site even suggests converting arguments to an array as an optimization.

Going to check with those who know JS interpreters more intimately...

Tamzin Blake
  • 2,594
  • 20
  • 36
  • In ES5, *arguments* is an Arguments object with clearly defined properties (ES5 §10.6). – RobG May 27 '11 at 03:40