Why the following code runs so.... slow....... ?
<html><body><script type="text/javascript">
var i = 0;
f();
function f() {
if (i == 5000开发者_Python百科) {
document.write("Done");
} else {
i++;
tail();
}
}
function tail() {
var fn = tail.caller;
var args = arguments;
setTimeout(function() {fn.apply(this, args)}, 0);
};
</script></body></html>
A couple of reasons:
Using the
caller
property on a function object introduces overhead (and is non-standard)The same for using the
arguments
pseudo-array (IIRC, this will slow down a function call by a factor of 2-5, depending on which browser you're using)setTimeout
will typically take no less than 10ms to call your function back (although Chrome sometimes goes a bit faster than that), even when you specify 0 as the timeout. This will probably be the biggest reason: 5,000 iterations at ~10ms is 50 seconds.
That last item is the reason I said:
If you have a lot of loop iterations (e.g., a couple of hundred instead of 15), it may well be worth doing a chunk of them on each iteration rather than yielding on each iteration; the yield takes a measureable time (typically ~10-15ms).
...in my answer to your other recent question.
Note that your code can be rewritten without using caller
or arguments
, making it much clearer:
var i = 0;
f();
function f() {
if (i == 5000) {
document.write("Done");
} else {
i++;
setTimeout(f, 0);
}
}
Separately: I notice you used document.write
in your code sample. If you're doing this with code executed during the page parse (which is the only place you can use document.write
), rather than in code you trigger with an event handler after the page is parsed, you can't use setTimeout
. This is because code that ouputs via document.write
has to run synchronously with the HTML parser on page load. Script blocks are executed during the parse for exactly this reason: In case they emit HTML the parser has to deal with. If you want to modify the page after parsing (which I'd recommend), you want to use DOM methods to get an element reference, and then either use DOM methods to add to it or (and this is both easier and faster running) set the innerHTML
property on the element.
My sense from both questions is that you probably do want to be looking into web workers, and only using the above for fallback for browsers that don't support them yet (IE, I'm afraid, but I bet IE9 will have them — and all the other major ones have them now).
精彩评论