Мне довольно любопытно на предмет того, что лучшая практика при ссылке на 'глобальное' пространство имен в JavaScript, который является просто ярлыком на window
объект (или недостаток versia в зависимости от того, как Вы смотрите на него).
Я хочу знать если:
var answer = Math.floor(value);
лучше или хуже, чем:
var answer = window.Math.floor(value);
Один лучше или хуже, даже немного, для производительности, использования ресурсов или совместимости?
У каждого есть более небольшая более высокая стоимость? (Что-то как дополнительный указатель или что-то)
Примечание редактирования: В то время как я - удобочитаемость по нацисту производительности в большинстве ситуаций, в этом случае я игнорирую различия в удобочитаемости, чтобы сфокусироваться только на производительности.
Прежде всего, никогда не сравнивайте такие вещи по причинам эффективности. 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 звонков). Если Math.round()
вызывается в локальной/функциональной области видимости, то интерпретатору придётся сначала проверить на наличие локального var, а затем в глобальном/оконном пространстве. Так что в локальной области видимости я предполагаю, что window.Math.round()
будет очень быстро. Это не сборка, не C или C++, так что я бы не беспокоился о том, какое из них быстрее по причинам производительности, но если из любопытства, конечно, проверим его на бенчмаркере.
Производительность JS широко отличается от браузера в браузере.
Мой совет: позоре это. Просто поместите его в цикл, дайте ему пройти несколько миллионов раз, и время его .... посмотрите, что вы получаете. Обязательно поделитесь своими результатами!
(Как Вы уже говорили) 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).
Насколько я понимаю логику JavaScript, все, что вы относитесь к , что-то
ищет в глобальной переменной области. В реализациях браузера окно
объект - глобальный объект. Следовательно, когда вы просите window.math
Вам на самом деле приходится от ссылки на то, что означает окно
, а затем получить его свойства и найти Математика
. Если вы просто попросите математику
, первое место, где он ищет, является глобальным объектом.
Итак, да, вызов Math. Что-то
будет быстрее окна . Math.something
.
d. Крокефорд рассказывает об этом в своей лекции http://video.yahoo.com/watch/111593/1710507 , насколько я помню, это в 3-й части видео.
Это может быть интересным вопросом, если вы хотите узнать, как работает цепь и разрешение идентификатора .
Цепочка охвата - это список объектов, которые ищеты при оценке идентификатора, эти объекты недоступны по коду, могут быть доступны только его свойства (идентификаторы).
Сначала в 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
нужен дополнительный шаг, который производится точкой (.
). ).