Javascript 空的try-catch如何影响性能?

Javascript 空的try-catch如何影响性能?,javascript,performance,google-chrome,try-catch,performance-testing,Javascript,Performance,Google Chrome,Try Catch,Performance Testing,我知道空的试试看。。。catch不是好的程序实践。但是,我想知道为什么空try。。。catch会影响JavaScript的性能吗 以下代码片段: function test() { var start = new Date(); for (var i = 0; i < 100000000; i++){ var r = i % 2; } console.log(new Date() - start); try { } c

我知道空的
试试看。。。catch
不是好的程序实践。但是,我想知道为什么空
try。。。catch
会影响JavaScript的性能吗

以下代码片段:

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) {

    }
}
运行时结果是
132

在正常情况下,

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) {

    }
}

结果是
130
,因此我认为
try-catch
函数范围
。我是对的还是遗漏了什么?

这非常依赖于JIT实现。不能在一般情况下回答这个问题

然而,您的基准很可能会给您带来误导性的结果,具体如下:

for (var i = 0; i < 100000000; i++){
    var r = i % 2;
}
for(变量i=0;i<100000000;i++){
var r=i%2;
}
即使是玩具编译器也可以将其优化为一个NOOP,无需太多额外的努力,就可以消除整个循环。这是因为它不会产生任何相关的副作用(“相关”如中所述,它对程序的输出没有影响,或者从较低的层次来看,它对将在其他地方访问的内存没有影响)

因此,对于任何一个像样的优化器,您基本上都是在计算什么都不做的成本(优化器会跳过您在很快意识到它没有影响用户输出的副作用后实际尝试进行基准测试的工作)

微基准是出了名的误导,因为优化器可以做什么。如果您不小心确保不能在不影响用户输出的情况下跳过工作,他们将跳过您正试图计时的工作

如果您想要构造有意义的基准测试,您通常希望至少以某种方式对计算进行聚合或求和,以使其成为用户输出。例如,您可以尝试将每次迭代中
r
的结果求和到某个外部变量中,该外部变量的值在计算结束时打印出来。这已经使得优化器跳过一系列计算变得越来越困难,在这一点上,无论是否使用空的
try/catch
块,以及是否在循环中放置
try/catch
,您都可能很快看到更多的可比时间

现在,根据您所看到的,这进入了一个猜测的领域,似乎引入空的try/catch块阻止了您的特定JIT能够跳过在该循环中完成的工作。编译器可能会在每个函数级别粗略地处理异常处理,归结为一种简单的“此函数是否需要异常处理?是/否?如果是,请避免对整个函数进行某些优化。”


这纯粹是一个有根据的猜测——唯一确定的方法是了解JIT的内部结构或查看生成的程序集。

我在chrome和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();
let数组=[];
函数test1(){
试一试{
console.log('begintest1..');
让startTime=新日期();
对于(设i=0;i<10000000;i++){
array.push(“”);
}
log('result:',new Date()-startTime);
}
捕捉(错误){
控制台错误(err);
}
}
函数test2(){
console.log('begintest2..');
让startTime=新日期();
对于(设i=0;i<10000000;i++){
array.push(“”);
}
log('result:',new Date()-startTime);
}
array.length=0;
test1();
array.length=0;
test2();
铬结果是:测试1中378ms,测试2中368ms(102%差异)。
Firefox的结果是:测试1中的1262ms与测试2中的1223ms(差异103%)

我测试了一些其他操作,如函数调用、除法和其他操作,但结果保持稳定


就目前而言,try/catch不会影响性能muchIt一般不会影响JS性能(因为该标准没有提供任何性能保证),它会影响一些特定的JS实现,这些JS实现无法像没有try-catch的代码一样优化使用try-catch的代码。相关:
for (var i = 0; i < 100000000; i++){
    var r = i % 2;
}
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();