Почему фабрики / закрытия JS намного медленнее, чем конструкторы / прототипы? - PullRequest
0 голосов
/ 28 декабря 2018

Когда-то фабрики / закрытия в JS когда-то были в пределах 15 процентов от конструкторов / прототипов.Сегодня разница составляет более 8000% в пользу прототипов (а прототипы используют около половины памяти).

https://jsperf.com/prototype-vs-factory-performance/4

Замыкания (теоретически) не создают больше объектов.У вас есть замыкание и экземпляр вместо прототипа и экземпляра (и у замыканий есть еще одно преимущество, поскольку вы не можете добавлять / удалять свойства из них).Мой единственный вывод заключается в том, что, хотя функции являются примитивами и неизменяемыми (хотя объекты функций не являются), они не интернированы, что вызывает скачки в кеше команд.Похоже, что это различие наблюдается в двигателях JS.

Есть ли у кого-нибудь какие-либо реальные факты о том, почему существует такое огромное неравенство?

1 Ответ

0 голосов
/ 28 декабря 2018

Закрытия (в теории) не создают больше объектов.

Этот стиль создания объекта "замыкание / фабрика" создает больше объектов: используя прототипы, экземпляры прототипаметоды являются общими, тогда как в стиле «фабрика» каждый экземпляр объекта получает свою собственную копию всех методов.Это наблюдаемо, так что это не то, что двигатель может просто оптимизировать.Подумайте:

var x1 = createValueObject();
var x2 = createValueObject();
x1.get.my_tag = 42;
console.log(x2.get.my_tag);      // undefined
console.log(x2.get === x1.get);  // false

var y1 = new ValueObject();
var y2 = new ValueObject();
y1.get.my_tag = 123;
console.log(y2.get.my_tag);      // 123
console.log(y2.get === y1.get);  // true

Я хотел бы подчеркнуть, что в целом использование укупорочных средств и фабрик совершенно нормально;этот пункт здесь применим только к этому конкретному шаблону создания объектов.


https://jsperf.com/prototype-vs-factory-performance/4

Это также прекрасный пример: Остерегайтесь вводящих в заблуждение микробенчмарков!

Всякий раз, когда вы видите сотни миллионов операций в секунду в тесте jsperf.com, тогда почти наверняка оптимизирующему компилятору удастся удалить весь ваш код, и вы 'перемерять пустые петли.На самом деле ни одна операция не является такой быстрой.

Это неудивительно в этом случае: использование прототипов - это идиоматический способ определения / создания объектов в JavaScript, и движки вкладывают много усилий в оптимизацию.каждый аспект этого шаблона, поэтому современные движки имеют возможность отслеживать, какие методы-прототипы вызываются, в конечном итоге их встроить (не сразу, только в горячий код!), выяснить, что они не дают полезных результатов, и отбросить всебесполезный код.

При правильном и тщательном тестировании можно ожидать, что то, что вы называете шаблоном «конструкторы / прототипы», все еще значительно быстрее, но не так быстро, как ошибочно указывают текущие результаты.


переполнение кэша команд

Нет, кэш инструкций не имеет к этому никакого отношения.

Когда-то фабрики / закрытияв JS были в пределах 15 процентов от конструкторов / прототипов.

Мне трудно поверить, что это имело место в любое время за последние десять лет.Может быть, 20 лет назад, когда все было медленно?

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