Updates:
Status: Assigned
Labels: -Type-Bug Type-FeatureRequest
Comment #1 on issue 1065 by [email protected]: try catch incurs an
unexpected performance penalty
http://code.google.com/p/v8/issues/detail?id=1065
The performance difference between try-catch #1 and try-catch #2 is because
parameter access is slower than local variable access for functions
containing with or try/catch, even for code outside the with or try/catch.
SVN revision 6426 on bleeding_edge removes the difference (by speeding up
parameters, not slowing down locals), so those two are on par with each
other.
There is still a difference from the baseline. Because of the with or
try/catch we allocate all the parameters and locals in the heap. The code
to read from such a variable is something like:
0xf54c3dc8 424 8b460b mov eax,[esi+0xb]
0xf54c3dcb 427 8b401f mov eax,[eax+0x1f]
as opposed to the code to read from a stack-allocated variable:
0xf54c3aa5 69 8b45f4 mov eax,[ebp+0xf4]
The extra read is to go from the current context (which may be a with
context) to the current function's context. In this case it's a nop
because they're the same and I think we can statically eliminate it (I'll
try).
The code to store to such a variable is, even for the case of a small
integer:
0xf54c3dce 430 8b4e0b mov ecx,[esi+0xb]
0xf54c3dd1 433 894123 mov [ecx+0x23],eax
0xf54c3dd4 436 89c2 mov edx,eax
0xf54c3dd6 438 f6c201 test_b edx,0x1
0xf54c3dd9 441 7424 jz 479 (0xf54c3dff)
:
:
0xf54c3dff 479 ....
as opposed to:
0xf54c3aa8 72 8945f0 mov [ebp+0xf0],eax
where the extra code in addition to the extra indirection is the write
barrier for heap writes. That's unfortunately a bit harder to avoid.
We should avoid treating try/catch as badly as with, but I'm not going to
get to that immediately. We should also be able to use the optimizing
compiler for code containing try/catch.
In the mean time, a performance recommendation is (a) remember that
using 'with' is slow, (b) for all code in the function, not just in the
body of the with, and (c) that try/catch is like with in this regard, (d)
so performance critical code should in such a function should be moved into
a helper function. The following code is on par with the baseline:
function body(j_, s) {
for (var i = 0; i < j_; i++) s = i;
for (var i = 0; i < j_; i++) s = i;
for (var i = 0; i < j_; i++) s = i;
for (var i = 0; i < j_; i++) s = i;
return s;
}
measure("try-catch #3", function try_catch_3 (j) {
try {
} catch (e) {
}
return body(j, 0);
}, 1000000);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev