{
var watch = performance.now();
let sum = 0;
for (let i = 0; i < 100_000_000; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
sum += val;
}
console.log(sum);
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
Здравствуйте, Pauel, Вы писали:
P>Подозреваю. все что в глобальном скопе, вообще полностью исполняется интерпретатором
И да и нет. Это из-за того, что переменные объявлены через var. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на let и все встает на свои места.
Здравствуйте, rFLY, Вы писали:
FLY>И да и нет. Это из-за того, что переменные объявлены через var. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на let и все встает на свои места.
Здравствуйте, Codealot, Вы писали:
C>Ну и жесть.
Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
Здравствуйте, rFLY, Вы писали:
C>>Ну и жесть. FLY>Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
Это офигенный ответ. Вообще, код ТС намекает, что он не из мира JS пришёл- элементарно линтер в проекте заругается на var и даже самому мелодичному танцору непозволит написать тот код.
Здравствуйте, Артём, Вы писали:
Аё>Вообще, код ТС намекает, что он не из мира JS пришёл- элементарно линтер в проекте заругается на var и даже самому мелодичному танцору непозволит написать тот код.
Казалось бы, что мешало знатокам сразу понять, в чем загвоздка?
Здравствуйте, rFLY, Вы писали:
FLY>Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
Здравствуйте, Codealot, Вы писали:
C>Осталось только понять, при чем здесь скорость.
Каждая переменная сохраняется в своем лексическом окружении, которое зависит от блока в котором переменная объявлена. По спецификации это некий объект, где сохраняются переменные и их значения (но реализация зависит от браузера). При обращении к переменной она ищется в локальном ЛО и если не находится, то во внешнем. Если не находится и там, то в еще более внешнем. И так пока не дойдет до глобального или не выдаст ошибку, что переменной не существует.
У тебя 3 блока:
1. for — отсюда начинается поиск используемых в цикле переменных, в том числе и var i
2. {} — блок в котором var sum и for
3. глобальный — здесь заканчивается, а все твои переменные попали в него (из-за использования устаревшего var). И помимо их там еще куча всякого.
Здравствуйте, Codealot, Вы писали:
FLY>>Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
C>Осталось только понять, при чем здесь скорость.
для глобального скопа работает только интерпретатор, подозреваю, что так. Это уменьшает время старта приложения/страницы
Как убрать код из глобального скопа — вам показали два варианта
Здравствуйте, Codealot, Вы писали:
FLY>>И да и нет. Это из-за того, что переменные объявлены через var. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на let и все встает на свои места.
C>Ну и жесть.
на SO такие кейсы иногда комментируют разработчики v8
Можете спросить у них, почему оптимизатор/джит не берутся за глобальный скоп
Здравствуйте, Codealot, Вы писали:
P>>Как убрать код из глобального скопа — вам показали два варианта
C>Если ты про rFLY, то никакого отношения к джиту это не имеет.
Что там точно происходит, вам никто кроме разработчиков V8 не скажет.
проседание производительности может происходить по следующим причинам
1. интерпретация — каждый файл до определенного выполняется интерпретатором, большинство успевает завершиться еще до того, как как рантайм решит джит подключать
2. деоптимизации — в вашем коде я их не наблюдаю
3. отсутствие инлайна — явных проблем с этим не видно
Здравствуйте, rFLY, Вы писали:
FLY>3. глобальный — здесь заканчивается, а все твои переменные попали в него (из-за использования устаревшего var). И помимо их там еще куча всякого.
FLY>Может кто-то поправит, но я вижу это так.
Пятикратная разница — как то слишком много для поиска переменной.
Подозреваю, если дело в поиске, то замена на global.x должна дать то же пятикратное отставание
Здравствуйте, Codealot, Вы писали:
P>>Что там точно происходит, вам никто кроме разработчиков V8 не скажет.
C>Если замена var на let полностью убирает разницу, то при чем здесь интерпретация?
Здравствуйте, Pauel, Вы писали:
P>Проверил, похоже это всё property lookup P>
P>globalThis.sum += val
P>
А если локальную переменную заменить на локальный объект (let sum = 0 на let o = {sum: 0})
//let sum = 0;
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
//sum += val;
o.sum += val;
}
то отработает еще на 120 быстрее (интел, эдж последней версии)
с let sum = 0
4999999950000000
1: 408.7000002861023
4999999950000000
2: 390.7999997138977
против
с let o = {sum: 0};
4999999950000000
1: 409.40000009536743
4999999950000000
2: 271.69999980926514