Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.01.2015, 03:05
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

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, 05.01.2015 в 03:17.
Ответить с цитированием
  #2 (permalink)  
Старый 05.01.2015, 07:56
Аватар для Erolast
Профессор
Отправить личное сообщение для Erolast Посмотреть профиль Найти все сообщения от Erolast
 
Регистрация: 24.09.2013
Сообщений: 1,436

Цитата:
- как не странно Chrome 41 показывается практически одинаковые результаты (хотя это как бы для V8 оптимизация https://github.com/petkaantonov/blue...ging-arguments)
- Firefox 35 в 5 раз быстрее!
- Safari 8 в 4 раза быстрее
- IE11 в 2 раза быстрее
Win7, intel core i3-2100 3.1GHz, Firefox 36 - в 16 раз быстрее

Последний раз редактировалось Erolast, 05.01.2015 в 08:19.
Ответить с цитированием
  #3 (permalink)  
Старый 05.01.2015, 11:31
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Octane, вторая функция разве не заменяется на это
Array.prototype.slice.call(arguments);

?
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 05.01.2015 в 11:34.
Ответить с цитированием
  #4 (permalink)  
Старый 05.01.2015, 15:17
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от nerv_
вторая функция разве не заменяется на это
Array.prototype.slice.call(arguments);
?
Судя по руководству Optimization killers, безопасно передать arguments можно только в apply.
Цитата:
What is safe arguments usage?

Only use

• arguments.length
• arguments[i] where i is always a valid integer index into the arguments, and can not be out of bound
• Never use arguments directly without .length or [i] (STRICTLY x.apply(y, arguments) is ok, nothing else is, e.g. .slice. Function#apply is special)

And note that the FUD about mentioning arguments causing an allocation of the arguments object is untrue when you use the it in the mentioned safe ways.
ну и на тестах это подтверждается, вариант с slice.call самый медленный http://jsperf.com/leaking-arguments/3

Последний раз редактировалось Octane, 05.01.2015 в 15:28.
Ответить с цитированием
  #5 (permalink)  
Старый 05.01.2015, 16:07
Профессор
Посмотреть профиль Найти все сообщения от krutoy
 
Регистрация: 09.11.2014
Сообщений: 610

Octane,
То что ты пишешь, больше похоже на пляски с бубнами и заклинания. Толк от таких мизерных оптимизаций будет только один: ты запутаешь и усложнишь код, и твое приложение будет тормозить раз в сто сильней.

К тому же, ты сравниваешь теплое с мягким. Ты в одном случае передаешь в f3 объект, а в другом -- массив. Возможно твои "тормоза" по большей части связаны с извлечением по ключу из объекта. return args[0];
Ответить с цитированием
  #6 (permalink)  
Старый 05.01.2015, 16:20
Профессор
Посмотреть профиль Найти все сообщения от krutoy
 
Регистрация: 09.11.2014
Сообщений: 610

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")

Последний раз редактировалось krutoy, 05.01.2015 в 16:26.
Ответить с цитированием
  #7 (permalink)  
Старый 05.01.2015, 16:31
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

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,                         \
    "Assignment to parameter, function uses arguments object")
а вот и место, где она кидается (hydrogen - это оптимизирующий движок в V8, если память не изменяет)
Код:
switch (var->location()) {
     case Variable::CONTEXT: {
        // Bail out if we try to mutate a parameter value in a function
        // using the arguments object.  We do not (yet) correctly handle the
        // arguments property of the function.
        if (current_info()->scope()->arguments() != NULL) {
          // Parameters will be allocated to context slots.  We have no
          // direct way to detect that the variable is a parameter so we do
          // a linear search of the parameter variables.
          int count = current_info()->scope()->num_parameters();
          for (int i = 0; i < count; ++i) {
            if (var == current_info()->scope()->parameter(i)) {
              Bailout(kAssignmentToParameterFunctionUsesArgumentsObject);
            }
          }
        }
сама Variable::CONTEXT

Код:
    // An indexed slot in a heap context.  index() is the variable index in
    // the context object on the heap, starting at 0.  scope() is the
    // corresponding scope.
    CONTEXT,
и теперь стало ещё непонятней ...
мало того, что на вопрос не ответил, так и сам запутался

в общем, если кто завладеет D8 в V8, отпишите сюда о результатах пож)

Последний раз редактировалось melky, 05.01.2015 в 16:53.
Ответить с цитированием
  #8 (permalink)  
Старый 05.01.2015, 16:48
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от krutoy
запутаешь и усложнишь код
Что сложного в том чтобы взять за правило: "не передавать arguments и не создавать ссылок на arguments"?
Сообщение от krutoy
Возможно твои "тормоза" по большей части связаны с извлечением по ключу из объекта. return args[0];
Это понятно. После вопроса nerv_ я добавил следующий тест, где есть 2 варианта с передачей массива.

Последний раз редактировалось Octane, 05.01.2015 в 17:01.
Ответить с цитированием
  #9 (permalink)  
Старый 05.01.2015, 17:07
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

melky, по-моему процетированный тобой код про это
(function (a) {
    arguments[0] = 2;
    alert(a);
}(1));
Ответить с цитированием
  #10 (permalink)  
Старый 05.01.2015, 17:23
Профессор
Посмотреть профиль Найти все сообщения от krutoy
 
Регистрация: 09.11.2014
Сообщений: 610

Сообщение от Octane
не передавать arguments и не создавать ссылок на arguments
Я серьзено спрашиваю. Ты можешь сказать, каким образом в твоем коде тестируется передача arguments?
Вот мое видение твоего кода. Ты что-то куда-то передаешь, что абсолютно не важно, что и куда. А затем уже, в итоге, ты сравниваешь производительность доступа к ключу объекта с доступом по ключу массива. Причем тут arguments ты можешь четко сказать?

Если я напишу

[1][0] vs {0: 1}[0]


Это тоже будет проверка arguments?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сделать из arguments массив Александр222 Общие вопросы Javascript 8 11.06.2014 00:52
Jin: И снова о наследовании tenshi Ваши сайты и скрипты 16 19.08.2013 20:30
помогите разобратся с arguments bot87 Общие вопросы Javascript 1 26.03.2012 15:33
Как создать экземпляр имея переменную arguments mexoboy Общие вопросы Javascript 13 01.11.2011 13:50
arguments вызвавшей функции mister_maxim Общие вопросы Javascript 4 12.10.2010 16:21