This page serves as a test case for the Mozilla bug report concerning tail-call optimization (TCO) in Javascript. It should highlight strange interferences between the proposed TCO and JIT. Turn JIT on or off, and you'll see the results vary.
System: windows 7 professional, dell optiplex 760, intel core quad cpu Q9650 3.00GHz, RAM 8.00 GB, 64 bits
Results: Duration of a single call, in seconds: the lower, the better.
Stack depth: case name Firefox 3.6 (JIT on) Firefox 3.6 (JIT off) Your browser & system
n: treeforeach_rec() 1.834e-4 s (100: base) 1.834e-4 s (100: base) 1.864e-4 s
n: treeforeach_tail() 2.220e-4 s (121) 2.192e-4 s (119) 2.095e-4 s
1: treeforeach_tailopt() 5.438e-4 s (296) 1.871e-4 s (102) 1.968e-4 s
n: DOMtreeforeach_rec() 2.156e-3 s (100: base) 1.905e-3 s (100: base) 4.119e-4 s
1: DOMtreeforeach_tail() 1.629e-3 s (76) 1.899e-3 s (100) 3.641e-4 s
1: DOMtreeforeach_tailopt() 2.904e-3 s (135) 1.823e-3 s (96) 3.461e-4 s
---
// treeforeach_rec: global.list[9].fun.toString():
function treeforeach_rec(tree, node_id, fun) {
var a, b, node = tree[node_id];
fun(tree, node_id);
for (b = 0; b < node.children.length; b++) {
treeforeach_rec(tree, node.children[b], fun);
}
}
---
// treeforeach_tail: global.list[10].fun.toString():
function treeforeach_tail(tree, node_id, fun) {
return function sub(_tree, _node_id, _fun, _from_below) {var _node = _tree[_node_id];if (!_from_below) {_fun(_tree, _node_id);if (_node.firstChild) {return sub(_tree, _node.firstChild, _fun, false);}}if (_node_id === node_id) {return;}if (_node.nextSibling) {return sub(_tree, _node.nextSibling, _fun, false);}if (_node.parent) {return sub(_tree, _node.parent, _fun, true);}return;}(tree, node_id, fun, false);
}
---
// treeforeach_tailopt: global.list[11].fun.toString():
function treeforeach_tail(tree, node_id, fun) {
var _tree = tree, _tree_new, _node_id = node_id, _node_id_new, _fun = fun, _fun_new, _from_below = false, _from_below_new;
L_sub:
while (true) {
var _node = _tree[_node_id];
if (!_from_below) {
_fun(_tree, _node_id);
if (_node.firstChild) {
_node_id_new = _node.firstChild;
_from_below_new = false;
_node_id = _node_id_new;
_from_below = _from_below_new;
continue L_sub;
}
}
if (_node_id === node_id) {
return;
}
if (_node.nextSibling) {
_node_id_new = _node.nextSibling;
_from_below_new = false;
_node_id = _node_id_new;
_from_below = _from_below_new;
continue L_sub;
}
if (_node.parent) {
_node_id_new = _node.parent;
_from_below_new = true;
_node_id = _node_id_new;
_from_below = _from_below_new;
continue L_sub;
}
return;
}
}
---
// DOMtreeforeach_rec: global.list[12].fun.toString():
function DOMtreeforeach_rec(node, fun) {
fun(node);
var a, c = node.childNodes;
for (a = 0; a < c.length; a++) {
DOMtreeforeach_rec(c[a], fun);
}
}
---
// DOMtreeforeach_tail: global.list[13].fun.toString():
function DOMtreeforeach_tail(node, fun) {
return function sub(_node, _fun, _from_below) {if (!_from_below) {_fun(_node);if (_node.firstChild) {return sub(_node.firstChild, _fun, false);}}if (_node.nextSibling) {return sub(_node.nextSibling, _fun, false);}if (_node.parentNode) {return sub(_node.parentNode, _fun, true);}return;}(node, fun, false);
}
---
// DOMtreeforeach_tailopt: global.list[14].fun.toString():
function DOMtreeforeach_tail(node, fun) {
var _node = node, _node_new, _fun = fun, _fun_new, _from_below = false, _from_below_new;
L_sub:
while (true) {
if (!_from_below) {
_fun(_node);
if (_node.firstChild) {
_node_new = _node.firstChild;
_from_below_new = false;
_node = _node_new;
_from_below = _from_below_new;
continue L_sub;
}
}
if (_node.nextSibling) {
_node_new = _node.nextSibling;
_from_below_new = false;
_node = _node_new;
_from_below = _from_below_new;
continue L_sub;
}
if (_node.parentNode) {
_node_new = _node.parentNode;
_from_below_new = true;
_node = _node_new;
_from_below = _from_below_new;
continue L_sub;
}
return;
}
}
_tailopt
*sometimes* runs
slower than _tail
and/or _rec
. fact_rec
and gcd_rec
).For the treeforeach_tail we need some text nodes with .js in them.
For the treeforeach_tail we need some text nodes with .js in them.
For the treeforeach_tail we need some text nodes with .js in them.
For the treeforeach_tail we need some text nodes with .js in them.
For the treeforeach_tail we need some text nodes with .js in them.
Produced on 2010-02-04 by mozilla-bug-report.scm - by Guillaume Lathoud (glathoud _at_ yahoo _dot_ fr)