|
(Rewritten to report results) I tried the following 4 variations in Node.js 0.6.13, V8 3.6.6.24. (The "global" business is for accessing the functions from a REPL.) var lots = 1000000;
// A: try/catch inside loop
global.a = function () {
for (var i=0; i<lots; i++) {
try { } catch (e) { }
}
}
// B: one try/catch, inlined loop
global.b = function () {
try {
for (var i=0; i<lots; i++) { }
} catch (e) { }
}
// C: one try/catch, loop in local function
global.c = function () {
var loop = function () {
for (var i=0; i<lots; i++) { }
}
try { loop(); } catch (e) { }
}
// D: one try/catch, loop in top-level function
function loop () {
for (var i=0; i<lots; i++) { }
}
global.d = function () {
try { loop(); } catch (e) { }
}
// E: no try/catch
global.e = function () { loop(); }
global.time = function (times, fn) {
var start = new Date().getTime();
for (var i=0; i<times; i += 1) { fn(); }
return (new Date().getTime() - start) / times;
};
In the REPL: > ({ a : time(100,a), b : time(100,b), c : time(100,c), d : time(100,d), e : time(100,e) });
{ a 7.66 b 5.29 c 5.06 d 1.45 e 1.32 }
So a million try/catches (A) is bad. But hoisting the try outside the loop (B) or putting the loop into a local function (C) doesn't do nearly as well as putting the loop in an outside function (D), which is almost as fast as no try/catch at all (E). I tried a few variations (like making the loop actually do some work) and the outcomes were all comparable.This clarifies and confirms what ef4 said: don't put cpu-intensive code inside the same function as a try/catch. Put it somewhere else and call it. Also, local functions don't necessarily count as "somewhere else". |