spam poison

JavaScript optimization, are chained calls expensive?

This acticle in other languages: Russian

...


Sree Kotay blogs about JavaScript a bit. (If you’re interested in more technical details, I’d recommend checking out Simon Willison’s “A (Re)-Introduction to JavaScript” presentation.) In Sree’s blog, he writes:

Part of understanding the distinction, in the trivial case, comes from the (obvious) understanding of basic JS optimization, that:

for (i=0; i<100; i++) a.b.c.d(v);

…is A LOT slower, at least in JavaScript, than:

var f=a.b.c.d;

for (i=0; i<100; i++) f(v);

…because after all, JS is a dynamic language. I’ll provide some specific JavaScript performance tips and JavaScript benchmarks to make the points clearly.

Now, I intuitively understand and agree with Sree that the latter should be faster, but exactly how much faster? Are symbol lookups in modern JavaScript engines actually that slow? Don’t modern JavaScript interpreters take advantage of JIT bytecode compilation and bytecode optimization, so that if you write the former code, it gets optimized behind the scenes into the latter form? (Whether this is possible through static analysis, I’m not sure of — I’m just throwing this question out there.)

Supposing it’s not possible to optimize away the inefficiency of the first form … what kind of performance penalty are we talking about? 1%? 10%? Is it a material difference that should drive a best practice around coding convention to avoid it? Out of sheer laziness, I’m only going to benchmark in Firefox 1.5.0.1 here on my 2.2 GHz Dell C840:

<script language="JavaScript">
var v = "Hello, world.";
var a = {
    b: {
        c: {
            d: function(arg) { return arg; }
        }
    }
};

document.write("<p>a.b.c.d(\"Hello, world.\") = " + a.b.c.d("Hello, world.") + "</p>");

var start = new Date();

for (var i = 0; i < 1000000; i++) {
    a.b.c.d(v);
}

var now = new Date();

document.write("<p>Difference: " + (now - start) + "</p>");

start = new Date();

var f = a.b.c.d;
for (var i = 0; i < 1000000; i++) {
    f(v);
}

now = new Date();

document.write("<p>Difference: " + (now - start) + "</p>");

</script>

The output:

a.b.c.d("Hello, world.") = Hello, world.

Difference: 2374

Difference: 1652

Since the JavaScript Date object provides time in milliseconds, we’re seeing one million iterations in 2374 milliseconds or 2.4 microseconds per iteration for the first form vs. one million iterations in 1652 milliseconds or 1.7 microseconds for the second form. We’re talking a difference of 0.7 microseconds per iteration, or a 29% difference. (Okay, my math skills are really weak, so I could be wrong here. Please double-check my numbers and let me know if I’ve gotten anything wrong, please.)

Okay, so 29% overhead is nothing to scoff at, but shaving 0.7 microseconds per iteration isn’t worth optimizing away when I’m guessing there’s lots of other coding practices where much more time is wasted. In other words, 90% of the time spent exeucting a script likely isn’t in that 29% of overhead, so it’s not where you should be focusing your optimization efforts.



Article information
Wroted: Wed, 08 Mar 2006 10:57:00 EET
Autors: Dossy Shiobara
Added by: AlexParamonov at Sun, 14 Dec 2008 13:33:12 EET
Translation information
This acticle in other languages: Russian
Added by: AlexParamonov at Sun, 14 Dec 2008 13:42:20 EET
Modified by: AlexParamonov at Sun, 14 Dec 2008 13:58:48 EET
Copyright © 2008-2010 Alexander Paramonov
Valid XHTML 1.0 Transitional