В JavaScript, получает доступ 'к окну. Математика' медленнее или быстрее, чем доступ к 'Математике' возражает без 'окна'.?

Мне довольно любопытно на предмет того, что лучшая практика при ссылке на 'глобальное' пространство имен в JavaScript, который является просто ярлыком на window объект (или недостаток versia в зависимости от того, как Вы смотрите на него).

Я хочу знать если:

var answer = Math.floor(value);

лучше или хуже, чем:

var answer = window.Math.floor(value);

Один лучше или хуже, даже немного, для производительности, использования ресурсов или совместимости?

У каждого есть более небольшая более высокая стоимость? (Что-то как дополнительный указатель или что-то)

Примечание редактирования: В то время как я - удобочитаемость по нацисту производительности в большинстве ситуаций, в этом случае я игнорирую различия в удобочитаемости, чтобы сфокусироваться только на производительности.

5
задан Mark Rogers 24 January 2010 в 03:45
поделиться

6 ответов

Прежде всего, никогда не сравнивайте такие вещи по причинам эффективности. Math.Round , очевидно, проще на глазах, чем в окне .math.rund , и вы не увидите заметного повышения производительности, используя один или другой. Так что не запутайте свой код для очень небольшого увеличения производительности.

Однако, если вам просто любопытно о том, какой из них быстрее ... Я не уверен, как глобальная область посмотрела «под капотом», но я догадаю, что доступ к окно Точно так же, как доступ к Math ( ( и математика в прямом эфире на одном уровне, что подтверждается окном . Window.window.math.ruund Работа). Таким образом, доступ к окну . Матч будет медленнее.

Кроме того, посмотрите, как переменные, вы увидите повышение производительности путем выполнения VAR Round = Math. Rood; и вызов (1.23) , поскольку все имена Сначала посмотрел в нынешнюю локальную область, затем объем над текущей, и так далее, вплоть до глобальной массы. Каждый уровень масштаба добавляет очень незначительный накладной расход.

Но опять же, не делайте этих оптимизаций, если вы не уверены, что они сделают заметную разницу. Читаемый, понятный код важен для этого, чтобы работать так, как он должен, теперь и в будущем.

Вот полный профилирование, используя Firebug:

<!DOCTYPE html>
<html>
    <head>
        <title>Benchmark scope lookup</title>
    </head>
    <body>
        <script>
        function bench_window_Math_round() {
            for (var i = 0; i < 100000; i++) {
                window.Math.round(1.23);
            }
        }

        function bench_Math_round() {
            for (var i = 0; i < 100000; i++) {
                Math.round(1.23);
            }
        }

        function bench_round() {
            for (var i = 0, round = Math.round; i < 100000; i++) {
                round(1.23);
            }
        }

        console.log('Profiling will begin in 3 seconds...');
        setTimeout(function () {
            console.profile();
            for (var i = 0; i < 10; i++) {
                bench_window_Math_round();
                bench_Math_round();
                bench_round();
            }
            console.profileEnd();
        }, 3000);
        </script>
    </body>
</html>

Мои результаты:
Время показывает всего 100 000 * 10 вызовов AVG / min / Макс Показать время на 100 000 звонков.

Calls  Percent  Own Time   Time       Avg        Min        Max
bench_window_Math_round
10     86.36%   1114.73ms  1114.73ms  111.473ms  110.827ms  114.018ms   
bench_Math_round
10      8.21%    106.04ms   106.04ms   10.604ms   10.252ms   13.446ms   
bench_round
10      5.43%     70.08ms    70.08ms    7.008ms    6.884ms    7.092ms

Как вы можете видеть, Window.Math - действительно плохая идея. Я думаю, что доступ к глобальному окно объект добавляет дополнительные накладные расходы. Однако разница между доступом к объекту Math из глобального охвата и просто доступа к локальной переменной со ссылкой на функцию функция не очень велика ... Помните, что это 100 000 звонков, и разница составляет всего 3,6 мс. Даже с миллионами звонков вы увидите только разницу в 36 мс.

Вещи, которые нужно подумать с вышеуказанным профилированием:

  • Функции на самом деле поднимаются вверх от другого объема, которые добавляют накладные расходы (даже заметны, я пытался импортировать функции в анонимную функцию).
  • Актуальная функция math.rund добавляет накладные расходы (я предполагаю, что около 6 мс в 100 000 звонков).
14
ответ дан 18 December 2019 в 07:54
поделиться

Если Math.round() вызывается в локальной/функциональной области видимости, то интерпретатору придётся сначала проверить на наличие локального var, а затем в глобальном/оконном пространстве. Так что в локальной области видимости я предполагаю, что window.Math.round() будет очень быстро. Это не сборка, не C или C++, так что я бы не беспокоился о том, какое из них быстрее по причинам производительности, но если из любопытства, конечно, проверим его на бенчмаркере.

0
ответ дан 18 December 2019 в 07:54
поделиться

Производительность JS широко отличается от браузера в браузере.

Мой совет: позоре это. Просто поместите его в цикл, дайте ему пройти несколько миллионов раз, и время его .... посмотрите, что вы получаете. Обязательно поделитесь своими результатами!

2
ответ дан 18 December 2019 в 07:54
поделиться

(Как Вы уже говорили) Math.floor, вероятно, будет просто ярлыком для window.Math (так как window является глобальным объектом Javascript) в большинстве реализаций Javascript, таких как V8.

Spidermonkey и V8 будут настолько сильно оптимизированы для общего использования, что это не должно быть проблемой.

Для удобочитаемости я бы предпочел использовать Math.floor, разница в скорости будет настолько незначительной, что беспокоиться не стоит. Если вы делаете 100,000 этажей, то, вероятно, пришло время переключить эту логику из клиента.

Возможно, вам захочется понаблюдать за источником v8, там есть несколько интересных комментариев о сбросе наносекунд с функций, таких как this int.Parse().

// Some people use parseInt instead of Math.floor.  This
// optimization makes parseInt on a Smi 12 times faster (60ns
// vs 800ns).  The following optimization makes parseInt on a
// non-Smi number 9 times faster (230ns vs 2070ns).  Together
// they make parseInt on a string 1.4% slower (274ns vs 270ns).
1
ответ дан 18 December 2019 в 07:54
поделиться

Насколько я понимаю логику JavaScript, все, что вы относитесь к , что-то ищет в глобальной переменной области. В реализациях браузера окно объект - глобальный объект. Следовательно, когда вы просите window.math Вам на самом деле приходится от ссылки на то, что означает окно , а затем получить его свойства и найти Математика . Если вы просто попросите математику , первое место, где он ищет, является глобальным объектом.

Итак, да, вызов Math. Что-то будет быстрее окна . Math.something .

d. Крокефорд рассказывает об этом в своей лекции http://video.yahoo.com/watch/111593/1710507 , насколько я помню, это в 3-й части видео.

1
ответ дан 18 December 2019 в 07:54
поделиться

Это может быть интересным вопросом, если вы хотите узнать, как работает цепь и разрешение идентификатора .

Цепочка охвата - это список объектов, которые ищеты при оценке идентификатора, эти объекты недоступны по коду, могут быть доступны только его свойства (идентификаторы).

Сначала в Global Code цепочка объема создается и инициализируется, чтобы содержать только глобальный объект.

Последующие объекты в цепочке создаются при входе в контексте выполнения функций, и по оператору с помощью , а также олова , оба также вводят объекты в цепочку.

Например:

// global code
var var1 = 1, var2 = 2;
(function () { // one
  var var3 = 3;
  (function () { // two
    var var4 = 4;

    with ({var5: 5}) { // three
      alert(var1);
    }
  })();
})();

В приведенном выше Кодексе цепочка охвата будет содержать различные объекты на разных уровнях, например, на самом низком уровне в с помощью , если вы используете var1 или var2 var2 var2 VAR2 Цепь охвата будет содержать 4 объекта, которые будут необходимы для проверки, чтобы получить этот идентификатор: тот, который представлен с помощью , две функции и, наконец, глобальный объект.

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

В заключение, когда вы используете окно , поскольку это просто идентификатор (не является зарезервированным словом или что-то подобное), и ему необходимо пройти весь процесс разрешения, чтобы получить глобальный объект , Window.Math нужен дополнительный шаг, который производится точкой (. ). ).

2
ответ дан 18 December 2019 в 07:54
поделиться
Другие вопросы по тегам:

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