Почему Math.floor JavaScript является самым медленным способом вычислить пол в JavaScript?

Я обычно - не поклонник микросравнительных тестов. Но у этого есть очень интересный результат.
http://ernestdelgado.com/archive/benchmark-on-the-floor/

Это предлагает это Math.floor САМЫЙ МЕДЛЕННЫЙ путь состоит в том, чтобы вычислить пол в JavaScript. ~~n, n|n, n&n причем весь быстрее.
Это кажется довольно шокирующим, поскольку я ожидал бы, что люди, реализующие JavaScript в сегодняшних современных браузерах, будут некоторыми довольно умными людьми.

Пол делает что-то важное, которое другим методам не удается сделать? Там какая-либо причина состоит в том, чтобы использовать его?

25
задан z5h 26 March 2010 в 20:55
поделиться

2 ответа

Это не имеет ничего общего с современными браузерами. Это связано с внедрением стандарта ECMA. Вы не можете просто изменить способ выполнения определенной функции, даже если есть более быстрый способ. Это может нарушить существующий код.

Math.Floor должен учитывать множество различных сценариев обработки различных типов. Могли ли они быстрее разрабатывать различные сценарии, сокращая путь, как вы описали? Может быть, они могли бы, но это могло сломать другие сценарии. То, что что-то на поверхности кажется маленьким, не означает, что под ним нет айсберга.

26
ответ дан 28 November 2019 в 18:31
поделиться

Основная причина, по которой Math.floor работает медленнее (там, где он есть - в некоторых тестах, которые я проводил быстрее), заключается в том, что он включает вызов функции. Старые реализации JavaScript не могли встроить вызовы функций. Новые движки могут встроить вызов или, по крайней мере, ускорить поиск свойств, но им по-прежнему требуется условие защиты на случай, если вы (или какой-либо другой скрипт) перезаписали функцию Math.floor . Однако накладные расходы минимальны, поэтому особой разницы в скорости нет.

Что еще более важно, как было упомянуто в нескольких комментариях , другие методы не эквивалентны . Все они работают, выполняя поразрядные операции. Поразрядные операторы автоматически преобразуют свои операнды в 32-разрядные целые числа путем усечения числа. Это нормально, если число умещается в 32 бита, но числа JavaScript являются 64-битными числами с плавающей запятой, которые могут быть намного больше, чем 2147483647.

Они также дают другой результат для отрицательных чисел, поскольку преобразование в целые числа обрезает и Math .floor всегда округляется в меньшую сторону. Например, Math.floor (-2.1) === -3 , но (- 2.1) | (-2,1) === -2 .

Если вы знаете , вы имеете дело только с положительными числами меньше 2147483648, и вам нужно выжать каждый бит производительности из вашего кода в старых браузерах (сначала убедитесь, что это узкое место. нет.), я бы использовал еще более простой метод: x | 0 . Он не вычисляет переменную дважды и работает, даже если x является выражением (просто не забудьте заключить его в круглые скобки, чтобы не столкнуться с проблемами приоритета).

32
ответ дан 28 November 2019 в 18:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: