2

Я знаю, что пустой try... 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) { 

    } 
} 

В результате время работы находится под 709Chrome

Тем не менее, без пустой try... catch,

function test3() { 
    var start = new Date(); 

    for (var i = 0; i < 100000000; i++){ 
     var r = i % 2; 
    } 

    console.log(new Date() - start); 

} 

В результате время работы является 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) { 

    } 
} 

В результате 792


Редактировать

Если я ставлю эту пустую try catch в другую функцию

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

    } 
} 

Результат 130, поэтому я думаю, что try catch является function scope. Я прав или чего-то не хватает?

+2

Это не влияет на производительность JS в целом (поскольку стандарт не дает никаких гарантий относительно производительности), он влияет на некоторые конкретные реализации JS, которые не могут оптимизировать код с try-catch так же хорошо, как и код без него. Релевантно: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers – zerkms

ответ

4

Это чрезвычайно зависит от реализации JIT. На него нельзя ответить в общем контексте.

Однако, ваш тест, скорее всего, дает вам ошибочные результаты, а именно здесь:

for (var i = 0; i < 100000000; i++){ 
    var r = i % 2; 
} 

Даже игрушечные компиляторы могут оптимизировать это в NOOP и без особых дополнительных усилий, устранить весь цикл. Это связано с тем, что он не вызывает никаких существенных побочных эффектов («релевантно», как в, он не влияет на выход программы или с точки зрения более низкого уровня, он не влияет на память, к которой будет обращаться в другом месте).

Итак, с любым достойным оптимизатором вы в основном тратите время на то, чтобы ничего не делать (оптимизатор просто пропустил работу, которую вы на самом деле пытаетесь оценить, после того как быстро понял, что у нее нет побочных эффектов, которые влияют на выход пользователя) ,

Микро-бенчмарки, как известно, вводят в заблуждение из-за того, что могут сделать оптимизаторы. Они пропустят ту самую работу, которую вы пытаетесь сделать, если не будете осторожны, чтобы убедиться, что работа не может быть пропущена, не затрагивая пользовательский вывод.

Если вы хотите сконструировать значащие тесты, вы, как правило, хотите как минимум суммировать или суммировать вычисления таким образом, чтобы он выводился пользователю. Например, вы можете попытаться суммировать результаты r на каждой итерации на некоторую внешнюю переменную, значение которой вы распечатываете в конце вычисления. Это уже сделало бы экспоненциально более сложным для оптимизатора пропустить кучу вычислений, после чего вы могли бы быстро начать видеть более сопоставимые времена с или без пустого блока try/catch и вне зависимости от того, помещаете ли вы try/catch вокруг цикла.

Теперь, основываясь на том, что вы видите, и это входит в сферу гипотезы, похоже, что введение пустого блока try/catch препятствует тому, чтобы ваш конкретный JIT мог пропустить работу, выполненную в этом цикле , Возможно, обработка исключений обрабатывается вашим компилятором грубым образом на уровне каждой функции, кипящей до простого типа, «Эта функция требует обработки исключений? Да/нет? Если да, избегайте определенных оптимизаций для целую функцию ".

Это чисто просвещенная догадка - единственный способ узнать наверняка - знать внутренности вашего JIT или посмотреть на полученную сборку.

Смежные вопросы