Почему цикл for занимает много времени, когда переменная определена в глобальной области видимости? - PullRequest
0 голосов
/ 03 июля 2019

В приведенном ниже примере, почему переменная занимает больше времени, чем впускает цикл? Я провел некоторое исследование по этому вопросу и обнаружил, что var определяет переменную глобально из-за функциональной области действия и позволяет определять переменную в области блока. вот почему ' var ' занимает больше времени, чем 'let', но все еще не может найти практического понимания, почему это так?

console.time('letCounter');
for (let letCounter = 0; letCounter < 10500; letCounter++) {
    console.log('letCounter', letCounter);
}
console.timeEnd('letCounter');
// 598.838134765625ms

console.time('varCounter');
for (var varCounter = 0; varCounter < 10500; varCounter++) {
    console.log('varCounter', varCounter);
}
console.timeEnd('varCounter');
// 656.56494140625ms

1 Ответ

1 голос
/ 03 июля 2019

Проблема с глобальными переменными состоит в том, что компилятор не может знать, будет ли доступ к контенту «внешними» функциями (т. Е. Когда тело не известно во время компиляции).

Например console.log может (теоретически) изменить varCounter, если это глобальная переменная.Затем переменная должна быть сохранена в полном слоте Javascript (способном содержать строки, массивы, объекты) и затем считывать данные из нее для выполнения приращения.

Если переменная вместо этого локальная, доступ невозможен, еслиvar не захватывается, и поэтому сама переменная может быть оптимизирована, и цикл может просто обнаружить шаблон и увеличить 32-битное целое число в качестве индекса, не выделяя полный слот Javascript.

Если переменная являетсяfunction-local var однако все по-другому, потому что внешняя функция к ним тоже не может получить доступ.В этом случае выполнение может быть даже быстрее с var, чем с let, если компилятор недостаточно умен: причина в том, что если в теле переменная потенциально захвачена замыканием, новая ячейка замыкания должна быть выделена вкаждая итерация.Этого не происходит с var, поскольку область видимости - это целая функция (а не тело цикла for):

 x = [];
 for (let i=0; i<10; ++) {
     x.push(()=>i);
 }
 console.log(x[4]()); // Shows 4

изменяя let на var в вышеуказанном цикле, вывместо этого получим 10, потому что все замыкания захватывают одну и ту же var ячейку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...