Здравствуйте, Pauel, Вы писали:
P>Подозреваю. все что в глобальном скопе, вообще полностью исполняется интерпретатором
И да и нет. Это из-за того, что переменные объявлены через var. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на let и все встает на свои места.
Здравствуйте, Codealot, Вы писали:
C>Мда, ну и муть.
Почему же, просто какой-то косяк в движке. Причем связанный с обращением к статическому свойству в конструкторе через имя класса:
class BaseClass
{
constructor()
{
this.Value = this.constructor.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
var func = function()
{
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
};
{
var watch = performance.now();
func();
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
BaseClass.Counter = 0;
{
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(`2: ${time}`);
}
Здравствуйте, 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
Код практически тот же. Разница в 5 раз. Какого хрена?
class BaseClass
{
constructor()
{
this.Value = BaseClass.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
var func = function()
{
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
};
{
var watch = performance.now();
func();
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
BaseClass.Counter = 0;
{
var watch = performance.now();
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
Здравствуйте, Codealot, Вы писали:
C>Ну и жесть.
Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
Здравствуйте, Codealot, Вы писали:
FLY>>Так работает var. Переменные объявленные через var (если только не объявлены внутри функции) в отличии от объявлений через let и const попадают в глобальный скоп. Можешь поставь точку останова внутри цикла и посмотреть.
C>Осталось только понять, при чем здесь скорость.
для глобального скопа работает только интерпретатор, подозреваю, что так. Это уменьшает время старта приложения/страницы
Как убрать код из глобального скопа — вам показали два варианта
надо байт-код посмотреть
Подозреваю что в первом случае компилятор понял что создавать объекты не нужно и можно обойтись инкрементом статического поля.
Добавь третий тест, в котором только инкремент, для проверки теории
А еще может быть что JIT решил метод func откомпилировать, тогда как основной скрипт работал в режиме интерпретатора.
Здравствуйте, vsb, Вы писали:
vsb>Могу предположить, что в первом случае он заинлайнил этот нуль и этот метод. Ну цикл, видимо, не заинлайнил, но уже был близок к этому.
vsb>А потом ты разрушил всю его хрупкую картину мира и он переделал всё "как надо".
Без разницы, в каком порядке их вызывать. Если один закомментировать, тоже без разницы.
Здравствуйте, Muxa, Вы писали:
M>Подозреваю что в первом случае компилятор понял что создавать объекты не нужно и можно обойтись инкрементом статического поля.
M>>Подозреваю что в первом случае компилятор понял что создавать объекты не нужно и можно обойтись инкрементом статического поля. C>Можно как-то этого избежать?
Наверно можно объекты в какой-то массив складывать, а затем один рандомный вывести в консоль.
Здравствуйте, Muxa, Вы писали:
M>Добавь третий тест, в котором только инкремент, для проверки теории
Дальше еще веселее.
4999999950000000
: 837.3000000119209
var watch = performance.now();
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
sum += i;
}
console.log(sum);
var time = performance.now() - watch;
console.log(`: ${time}`);
Здравствуйте, Codealot, Вы писали:
C>Дальше еще веселее. C>4999999950000000 C>: 837.3000000119209 C>
C>
C> var watch = performance.now();
C> var sum = 0;
C> for (var i = 0; i < 100_000_000; i++)
C> {
C> sum += i;
C> }
C> console.log(sum);
C> var time = performance.now() - watch;
C> console.log(`: ${time}`);
C>
Здравствуйте, Codealot, Вы писали:
P>>Подозреваю. все что в гобальном скопе, вообще полностью исполняется интерпретатором
C>Зачем? И как это проверить точно?
Оборачиваете в функцию, и всё, второй блок внезапно ускоряется
Оборачиваем только второй блок
class BaseClass
{
constructor()
{
this.Value = BaseClass.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
var func = function()
{
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
};
{
var watch = performance.now();
func();
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
BaseClass.Counter = 0;
(function x() {
var watch = performance.now();
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
var time = performance.now() - watch;
console.log(`1: ${time}`);
}) ();
Оборачиваем всё, тот же эффект
(function x() {class BaseClass
{
constructor()
{
this.Value = BaseClass.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
var func = function()
{
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
};
{
var watch = performance.now();
func();
var time = performance.now() - watch;
console.log(`1: ${time}`);
}
BaseClass.Counter = 0;
var watch = performance.now();
var sum = 0;
for (var i = 0; i < 100_000_000; i++)
{
var obj = new BaseClass();
var val = obj.TestMethod();
sum += val;
}
console.log(sum);
var time = performance.now() - watch;
console.log(`1: ${time}`);
}) ();
{
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}`);
}
Здравствуйте, rFLY, Вы писали:
FLY>И да и нет. Это из-за того, что переменные объявлены через var. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на let и все встает на свои места.
Здравствуйте, 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. В скопе функции это роли не играет, а вот в глобальном получаются доп расходы. Стоит заменить на 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 полностью убирает разницу, то при чем здесь интерпретация?
Здравствуйте, Codealot, Вы писали:
C>Это еще что за зверь?
Кто, let o = {sum: 0}? Обычный объект со свойством sum, только объявленный в литеральной форме (JSON же знаешь как выглядит?). Создается сразу при объявлении.
console.log("Пустой при объявлении объект");
var obj1 = {};
console.log(obj1);
// Добавить свойства и методы
obj1.prop1 = "значение Prop1";
obj1.getProp1 = function() {
return this.prop1;
}
console.log(obj1.getProp1());
console.log(obj1);
console.log("Тоже, но сразу со свойствами и методами");
var obj2 = {
prop1: "значение Prop1",
getProp1: function() {
return this.prop1;
}
}
console.log(obj2.getProp1());
console.log(obj2);
Здравствуйте, rFLY, Вы писали:
FLY>А если локальную переменную заменить на локальный объект (let sum = 0 на let o = {sum: 0})
FLY>то отработает еще на 120 быстрее (интел, эдж последней версии)
У меня ноутбучный проц i7 22го года, отрабатывает за 900 и 600, т.е. в полтора раза стало быстрее.
А есть какое внятное объяснение этому? inline cache включается или что?
Здравствуйте, Pauel, Вы писали:
P>А есть какое внятное объяснение этому? inline cache включается или что?
Вроде в ноде можно дизассемблировать при помощи следующего флага и посмотреть что там творится.
node --print_opt_code test.js
У меня тут ноды нет, так что посмотреть не могу. Могу лишь предположить, что значение свойства sum записывается в регистр, а после цикла обратно, в то время как при работе с переменной при каждой итерации используется ее адрес. А может и еще что делается.
UPD: Стало интересно и решил поэксперементировать
class BaseClass
{
constructor()
{
this.Value = BaseClass.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
console.log("без создания объекта");
{
let watch = performance.now();
let sum = 0;
for (let i = 0; i < 100_000_000; i++)
sum += i;
console.log(`var_: ${performance.now() - watch}`);
}
{
let watch = performance.now();
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++)
o.sum += i;
console.log(`prop: ${performance.now() - watch}`);
}
console.log("с созданием объекта");
{
let watch = performance.now();
let sum = 0;
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
sum += i;
}
console.log(`var_: ${performance.now() - watch}`);
}
{
let watch = performance.now();
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
o.sum += i;
}
console.log(`prop: ${performance.now() - watch}`);
}
без создания объекта
var_: 58.90000009536743
prop: 200.90000009536743
с созданием объекта
var_: 326.1000003814697
prop: 223.5
То есть на итог влияет new BaseClass(). С ним, даже если объект не используется, суммирование через переменную существенно просаживается.
Здравствуйте, rFLY, Вы писали:
FLY>То есть на итог влияет new BaseClass(). С ним, даже если объект не используется, суммирование через переменную существенно просаживается.
сумма — короткая операция. Вы, условно, умножаете издержки просто дёргая new BaseClass();
new BaseClass — выделение памяти, инициализация
BaseClass.Counter — лукап
++ — сравнимо с += в основном цикле
this.Value — еще один лукап
Здравствуйте, Pauel, Вы писали:
P>new BaseClass — выделение памяти, инициализация P>BaseClass.Counter — лукап P>++ — сравнимо с += в основном цикле P>this.Value — еще один лукап
Ты не понял или не вникал в написанное. Создание объекта не просто приводит к замедлению, а меняет время выполнения (и только при использовании переменной для суммы) на противоположный. При вычислении суммы через свойство объекта о.sum различия во времени минимальны. Повторю укороченно, если код проигнорировал:
// без new BaseClass()let sum = 0;
for (let i = 0; i < 100_000_000; i++)
sum += i;
// и
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++)
o.sum += i;
// против следующего, но с добавлением new BaseClass()let sum = 0;
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
sum += i;
}
// и
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
o.sum += i;
}
}
вычисление переменной let sum c new BaseClass становится дороже чем аналогичное, но через o.sum, а без new BaseClass() наоборот.
Здравствуйте, rFLY, Вы писали:
FLY>вычисление переменной let sum c new BaseClass становится дороже чем аналогичное, но через o.sum, а без new BaseClass() наоборот.
Что тут странного? Джит крайне ограничен, во всех платформах. чуть не так — отваливается та или иная оптимизация.
Здравствуйте, Pauel, Вы писали:
P>Что тут странного? Джит крайне ограничен, во всех платформах. чуть не так — отваливается та или иная оптимизация.
А что в sum += i оптимизировать? Впрочем причина нашлась, если интересно см. ответ выше.
Здравствуйте, rFLY, Вы писали:
P>>Что тут странного? Джит крайне ограничен, во всех платформах. чуть не так — отваливается та или иная оптимизация. FLY>А что в sum += i оптимизировать? Впрочем причина нашлась, если интересно см. ответ выше.
Я бы предположил, что джит делает не любые возможные оптимизации, а только те, на которые у него капасити хватает.
Здравствуйте, rFLY, Вы писали:
FLY>Здравствуйте, Codealot, Вы писали:
C>>Мда, ну и муть. FLY>Почему же, просто какой-то косяк в движке. Причем связанный с обращением к статическому свойству в конструкторе через имя класса:
Это не косяк, это тот же lookup, что и с поиском в глобальном скопе
Вот смотрите — если вместо class BaseClass написать const BaseClass = class { ... то получится ровно то же, что и у вас
Смотрите сами
без создания объекта
var_: 67.20000000018626
prop: 208.29999999981374
с созданием объекта
var_: 89.90000000037253
prop: 203.90000000037253
Собственно, если просто заверуть всё в функцию, это ничем не помогает. Все дело именно в том, куда запихивается class BaseClass. Похоже, это какой то конский объект.
А вот объявление класса через const меняет дело
const BaseClass = class
{
constructor()
{
this.Value = BaseClass.Counter++;
}
TestMethod()
{
return this.Value;
}
static Counter = 0;
}
console.log("без создания объекта");
{
let watch = performance.now();
let sum = 0;
for (let i = 0; i < 100_000_000; i++)
sum += i;
console.log(`var_: ${performance.now() - watch}`);
}
{
let watch = performance.now();
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++)
o.sum += i;
console.log(`prop: ${performance.now() - watch}`);
}
console.log("с созданием объекта");
{
let watch = performance.now();
let sum = 0;
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
sum += i;
}
console.log(`var_: ${performance.now() - watch}`);
}
{
let watch = performance.now();
let o = {sum: 0};
for (let i = 0; i < 100_000_000; i++) {
new BaseClass();
o.sum += i;
}
console.log(`prop: ${performance.now() - watch}`);
}
Здравствуйте, Pauel, Вы писали:
P>Это не косяк, это тот же lookup, что и с поиском в глобальном скопе
Да, но в таком случае обращение к BaseClass.Counter не должно делать sum += value медленнее чем obj.sum += value. Почему высчитывание суммы через свойство объекта вдруг стало производительнее чем через обычную переменную? И там и там лукап в конструкторе класса и время просчета суммы для обоих способов должно было измениться пропорционально. Вот в этом я вижу косяк.
Здравствуйте, rFLY, Вы писали:
FLY>Да, но в таком случае обращение к BaseClass.Counter не должно делать sum += value медленнее чем obj.sum += value. Почему высчитывание суммы через свойство объекта вдруг стало производительнее чем через обычную переменную? И там и там лукап в конструкторе класса и время просчета суммы для обоих способов должно было измениться пропорционально. Вот в этом я вижу косяк.
Это поведение очень похоже на работу inline cache
У него капасити крохотный, +1 лишний лукап и уже отставание в разы
Здравствуйте, Pauel, Вы писали:
P>Покажите код, у меня чтото не получается воспроизвести
282.75
1442.3100000023842
Только в хроме, в фаерфоксе такого эффекта нет.
'use strict';
const TestsNumber = 10;
const ItemsNumber = 100_000_000;
function Test(func)
{
let totalTime = 0;
for (let i = 0; i < TestsNumber; i++)
{
let watch = performance.now();
func();
let curTime = performance.now() - watch;
totalTime += curTime;
}
console.log(totalTime / TestsNumber);
}
class BaseClass
{
TestMethod()
{
this.Value = BaseClass.Counter++;
return this.Value;
}
static Counter = 0;
}
Test(function()
{
let obj = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
obj.sum += val;
}
});
Test(function()
{
let sum = 0;
for (let i = 0; i < ItemsNumber; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
sum += val;
}
});
Здравствуйте, Codealot, Вы писали:
C>Похоже, не только в конструкторе. И еше если использовать C>
C>let obj = { sum: 0 };
C>
C>а потом C>
C>let sum = 0;
C>
C>(или наоборот), то производительность второго варианта просаживается раз в 5.
Это следствие, а не причина. Если изменить конструктор (то, о чем писал я) или использовать модификатор const в объявлении класса (как предложил Pauel), то все начинает работать ожидаемо.
Здравствуйте, Codealot, Вы писали: C>Здравствуйте, Codealot, Вы писали: C>Хотя похоже, что без разницы, какой из вариантов используется. Второй всегда тормозит.
У тебя ошибка — внешний obj не используется, вместо него внутри цикла ты пишешь значение в только что созданный объект
let obj = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
obj.sum += val;
}
Вот результаты теста по нескольким вариантам
Свойство 'o.sum' и BaseClass с BaseClass.Counter++
342.70000000298023
Переменная 'sum' и BaseClass с BaseClass.Counter++
406.09999999403954
Свойство 'o.sum' и ConstClass с ConstClass.Counter++
179.20000000298023
Переменная 'sum' и ConstClass с ConstClass.Counter++
90
Свойство 'o.sum' и this.constructor.Counter++
183.09999999403954
Переменная 'sum' и this.constructor.Counter++
84.59999999403954
Свойство 'o.sum' и prototype
178.80000001192093
Переменная 'sum' и prototype
84.40000000596046
сам скрипт тестирования
const TestsNumber = 1;
const ItemsNumber = 100_000_000;
function Test(func) {
let totalTime = 0;
for (let i = 0; i < TestsNumber; i++) {
let watch = performance.now();
func();
let curTime = performance.now() - watch;
totalTime += curTime;
}
console.log(totalTime / TestsNumber);
}
// BaseClass.Counter++
class BaseClass
{
TestMethod() {
this.Value = BaseClass.Counter++;
return this.Value;
}
static Counter = 0;
}
console.log("Свойство 'o.sum' и BaseClass с BaseClass.Counter++");
Test(function() {
let o = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++) {
let obj = new BaseClass();
let val = obj.TestMethod();
o.sum += val;
}
});
console.log("Переменная 'sum' и BaseClass с BaseClass.Counter++");
BaseClass.Counter = 0;
Test(function() {
let sum = 0;
for (let i = 0; i < ItemsNumber; i++) {
let obj = new BaseClass();
let val = obj.TestMethod();
sum += val;
}
});
// const class
const ConstClass = class
{
TestMethod() {
this.Value = ConstClass.Counter++;
return this.Value;
}
static Counter = 0;
}
console.log("\nСвойство 'o.sum' и ConstClass с ConstClass.Counter++");
Test(function() {
let o = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++) {
let obj = new ConstClass();
let val = obj.TestMethod();
o.sum += val;
}
});
console.log("Переменная 'sum' и ConstClass с ConstClass.Counter++");
ConstClass.Counter = 0;
Test(function() {
let sum = 0;
for (let i = 0; i < ItemsNumber; i++) {
let obj = new ConstClass();
let val = obj.TestMethod();
sum += val;
}
});
// через this.constructor.Counter
class BaseClass2
{
TestMethod() {
this.Value = this.constructor.Counter++;
return this.Value;
}
static Counter = 0;
}
console.log("\nСвойство 'o.sum' и this.constructor.Counter++")
Test(function() {
let o = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++) {
let obj = new BaseClass2();
let val = obj.TestMethod();
o.sum += val;
}
});
console.log("Переменная 'sum' и this.constructor.Counter++")
BaseClass2.Counter = 0;
Test(function() {
let sum = 0;
for (let i = 0; i < ItemsNumber; i++) {
let obj = new BaseClass2();
let val = obj.TestMethod();
sum += val;
}
});
// По-старинке
class ProtoClass
{
TestMethod() {
this.Value = Object.getPrototypeOf(this).Counter++;
return this.Value;
}
}
ProtoClass.prototype.Counter = 0;
console.log("\nСвойство 'o.sum' и prototype");
Test(function() {
let o = { sum: 0 };
for (let i = 0; i < ItemsNumber; i++) {
let obj = new ProtoClass();
let val = obj.TestMethod();
o.sum += val;
}
});
console.log("Переменная 'sum' и prototype");
ProtoClass.prototype.Counter = 0;
Test(function() {
let sum = 0;
for (let i = 0; i < ItemsNumber; i++) {
let obj = new ProtoClass();
let val = obj.TestMethod();
sum += val;
}
});
Здравствуйте, rFLY, Вы писали:
FLY>У тебя ошибка — внешний obj не используется, вместо него внутри цикла ты пишешь значение в только что созданный объект
Да, есть такое дело. Но по скорости пофиг:
336.42000000029805
1444.9300000000744
let func = function()
{
let sum = 0;
for (let i = 0; i < ItemsNumber; i++)
{
let obj = new BaseClass();
let val = obj.TestMethod();
sum += val;
}
};
Test(func);
Test(func);