Прежде всего, никогда не сравнивайте подобные вещи по соображениям производительности. Math.round
явно проще для глаз, чем window.Math.round
, и вы не заметите заметного увеличения производительности при использовании одного или другого. Так что не запутывайте свой код для очень небольшого увеличения производительности.
Однако, если вам просто любопытно, какой из них быстрее ... Я не уверен, как глобальная область видится "под капотом", но я думаю, что доступ к window
точно такой же как доступ к Math
(window
и Math
живут на одном уровне, о чем свидетельствует window.window.window.Math.round
работает). Таким образом, доступ к window.Math
будет медленнее.
Кроме того, при поиске переменных вы увидите увеличение производительности, выполнив var round = Math.round;
и вызвав round(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>
Мои результаты:
Time
показывает общее количество для 100 000 * 10 вызовов, Avg
/ Min
/ Max
показывает время для 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
действительно плохая идея. Я предполагаю, что доступ к глобальному объекту window
добавляет дополнительные издержки. Однако разница между доступом к объекту Math
из глобальной области и простым обращением к локальной переменной со ссылкой на функцию Math.round
не очень велика ... Имейте в виду, что это 100 000 вызовов, и разница составляет всего 3,6 мс. Даже при миллионе вызовов вы увидите разницу только в 36 мс.
О чем следует подумать с помощью приведенного выше кода профилирования:
- На самом деле функции ищутся из другой области видимости, что добавляет издержки (хотя это было едва заметно, я попытался импортировать функции в анонимную функцию).
- Фактическая функция
Math.round
добавляет издержки (я предполагаю, что около 6 мс на 100 000 вызовов).