Reputation: 48366
I know the empty try... catch
is not good program practice. However, I want to know the reason why the empty try... catch
affect the performance in JavaScript?
The following codes snippets:
function test() {
var start = new Date();
for (var i = 0; i < 100000000; i++){
var r = i % 2;
}
console.log(new Date() - start);
try {
} catch (ex) {
}
}
The run time result is 709
under Chrome
However, without the empty try... catch
,
function test3() {
var start = new Date();
for (var i = 0; i < 100000000; i++){
var r = i % 2;
}
console.log(new Date() - start);
}
The run time result is 132
.
Under normal circumstances,
function test1() {
var start = new Date();
try {
for (var i = 0; i < 100000000; i++){
var r = i % 2;
}
console.log(new Date() - start);
} catch (ex) {
}
}
The result is 792
Edit
If I put this empty try catch
into another function
function test4() {
var start = new Date();
for (var i = 0; i < 100000000; i++){
var r = i % 2;
}
console.log(new Date() - start);
wrap();
}
function wrap() {
try {
} catch (ex) {
}
}
The result is 130
, so I think the try catch
is function scope
. Am I right or missing something?
Upvotes: 2
Views: 426
Reputation: 96
I ran two tests in chrome and firefox:
let array = [];
function test1(){
try{
console.log('begin test 1..');
let startTime = new Date();
for(let i = 0; i < 10000000;i++){
array.push('');
}
console.log('result: ', new Date() - startTime);
}
catch(err){
console.error(err);
}
}
function test2(){
console.log('begin test 2..');
let startTime = new Date();
for(let i = 0; i < 10000000;i++){
array.push('');
}
console.log('result: ', new Date() - startTime);
}
array.length = 0;
test1();
array.length = 0;
test2();
Chrome result is: 378ms in test 1 vs 368ms in test 2 (102% diff).
Firefox result is: 1262ms in test 1 vs 1223ms in test 2 (103% diff)
I've tested some other operations like function calls, dividing and other, but result stays stable.
Upvotes: 0
Reputation:
That's extremely dependent on the JIT implementation. It can't be answered in a general context.
However, your benchmark is most likely giving you misleading results, specifically here:
for (var i = 0; i < 100000000; i++){
var r = i % 2;
}
Even toy compilers can optimize this into a NOOP and, without much extra effort, eliminate the entire loop. It's because this invokes no relevant side effects whatsoever ("relevant" as in, it has no effect on the output of the program, or from a lower-level perspective, it has no effect on memory that is going to be accessed elsewhere).
So with any decent optimizer, you're basically timing the cost of doing nothing at all (the optimizer would just skip the work you're actually trying to benchmark after quickly realizing it has no side effects that affect user output).
Micro-benchmarks are notoriously misleading because of what optimizers can do. They'll skip the very work you're trying to time if you aren't careful to make sure the work cannot be skipped without affecting user output.
If you want to construct meaningful benchmarks, you typically want to at least aggregate or sum the computation in some way that makes it to user output. For example, you might try summing the results of r
in each iteration into some outer variable whose value you print out at the end of the computation. That would already make it exponentially more difficult for the optimizer to skip a bunch of computations, at which point you might quickly start to see more comparable times with or without the empty try/catch
block, and whether or not you put a try/catch
around the loop.
Now, based on what you're seeing, and this is getting into a realm of conjecture, it appears like introducing the empty try/catch block is preventing your particular JIT from being able to skip the work done in that loop. It's possible that exception-handling is being treated coarsely by your compiler at a per-function level, boiling down to a simple kind of, "Does this function require exception-handling? Yes/no? If yes, avoid certain optimizations for the entire function."
That's purely an educated guess -- only way to know for sure is to know the internals of your JIT or look at the resulting assembly.
Upvotes: 5