fix leaking arguments
Речь о том, чтобы никуда не передавать и не создавать ссылки на arguments, иначе выключаются оптимизации.
Пример:
function f1() {
f3(arguments);
}
function f2() {
var i = arguments.length;
var args = new Array(i);
while (i--) {
args[i] = arguments[i];
}
f3(args);
}
function f3(args) {
return args[0];
}
Как выяснилось по тестам http://jsperf.com/leaking-arguments/2 код с функцией f2 работает гораздо быстрее, не смотря на то, что выполняет лишние действия. На mbp c core i5 2.4GHz: - как не странно Chrome 41 показывается практически одинаковые результаты (хотя это как бы для V8 оптимизация https://github.com/petkaantonov/blue...ging-arguments) - Firefox 35 в 5 раз быстрее! - Safari 8 в 4 раза быстрее - IE11 в 2 раза быстрее Что-то я раньше не придавал этому большого значения, думал что это только для V8 актуально, а он и так быстрый, но как оказалось следует так делать для всех браузеров. |
Цитата:
|
Octane, вторая функция разве не заменяется на это
Array.prototype.slice.call(arguments); ? |
Цитата:
Цитата:
|
Octane,
То что ты пишешь, больше похоже на пляски с бубнами и заклинания. Толк от таких мизерных оптимизаций будет только один: ты запутаешь и усложнишь код, и твое приложение будет тормозить раз в сто сильней. К тому же, ты сравниваешь теплое с мягким. Ты в одном случае передаешь в f3 объект, а в другом -- массив. Возможно твои "тормоза" по большей части связаны с извлечением по ключу из объекта. return args[0]; |
Octane,
вот объективное сравнние, из которого видно, что сам объект аргументс тут не причем. И он даже выигрывает в V8, кстати. UPD в FF -- тоже
function f1() {
f3(arguments);
}
function f2(args) {
f3(args);
}
function f3(args) {
return args[0];
}
i=100000
console.time("f1")
while(i--) f1(1,2,3)
console.timeEnd("f1")
i=100000
console.time("f2")
while(i--) f2({0: 1, 1: 2, 2: 3})
console.timeEnd("f2")
|
Octane, хай. может быть поможет: ссылька
было бы круто заиметь окружение тестирования V8 в своих тестах, чтобы писать типа:
var lib = require('my-lib');
MUST_OPTIMIZE_NEXT_CALL('Передача числа');
lib.atan(45);
MUST_OPTIMIZE_NEXT_CALL('Передача строки'); // функция деоптимизируется. тест кинет ошибку здесь с сообщением "Передача строки"
lib.atan('ЙОЙО');
я вроде помню, во внутренних тестах V8 есть такой ужас(MUST_OPTIMIZE...), но как получить к этому доступ - хз ну а чтобы конкретно ответить на твой вопрос, нужно качать dev версию v8 на линуксах, вызывать js код из него и смотреть лог движка. сейчас уже нельзя с уверенностью ничего сказать, ибо за год в движках могло многое измениться вот причины деооптимизаций. там есть: Код:
V(kAssignmentToParameterFunctionUsesArgumentsObject, \Код:
switch (var->location()) {Код:
// An indexed slot in a heap context. index() is the variable index inмало того, что на вопрос не ответил, так и сам запутался :) в общем, если кто завладеет D8 в V8, отпишите сюда о результатах пож) |
Цитата:
Цитата:
|
melky, по-моему процетированный тобой код про это
(function (a) {
arguments[0] = 2;
alert(a);
}(1));
|
Цитата:
Вот мое видение твоего кода. Ты что-то куда-то передаешь, что абсолютно не важно, что и куда. А затем уже, в итоге, ты сравниваешь производительность доступа к ключу объекта с доступом по ключу массива. Причем тут arguments ты можешь четко сказать? Если я напишу
[1][0] vs {0: 1}[0]
Это тоже будет проверка arguments? |
Да знаю я, что значения массива быстрее достаются, чем свойства объекта.
Цитата:
|
Цитата:
Не совсем понятно, куда может потребоваться передавать ссылку на аргументы. Разве что, на данный момент, за неимением классов из es6. |
Да в Chrome иногда даже немного медленее, поэтому и думал, что это хреновый совет в руководстве Optimization-killers, которое читал пол года или больше назад, а сейчас что-то дорвался проверить в других браузерах :)
|
Цитата:
Что касается V8: сегодня он работает так, завтра по другому, послезавтра V9. :) |
| Часовой пояс GMT +3, время: 19:06. |