Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Зацените (https://javascript.ru/forum/project/1542-zacenite.html)

Dmitry A. Soshnikov 11.08.2008 01:34

Андрей Параничев, да, я сразу не заметил, но ZoNT, возможно, просто не знаком с контекстами и не видит, что глобальная переменная для объекта Global (в браузере Global === window) будет (относительно scope'a) играть такую роль же, как локальная переменная в функции. Поэтому, чтобы проводить опыты, чтобы эмпирически подтверждать теорию, надо конкретно, однозначно определить - какие переменные (какого скопа) участвуют в тестах.

Цитата:

Сообщение от ZoNT
На него заходят нубы и задают вопросы. И им надо разжовывать.

ZoNT, разжевываю:

var a = 10; - глобальная переменная
alert(window['a']); // это свойство объекта Global (window)

function test() {
  var c = 20; - локальная переменная
  alert([c, a]);
}


Переменная "c" стала свойством объекта variable object (10.1.3) - этот объект имеется у каждой функции и хранит все локальные переменные, все формальные параметры, а также все декларации функций. Т.е. в нашем случае variable object (далее для сокращения - VO) функции "test" имеет одно свойство "c". Схематично отобразим так:

VO(test) = {c: 20};


Далее, мы видим alert([c, a]);. Спрашивается, откуда выдается "20,10", если VO(test) не имеет у себя свойства "а"? А дело в scope chain'e (10.1.4) - цепи скопов (variable object'ов, начиная от VO функции и вверх до родительских скопов), которые хранит функция. Это еще один объект (хранится во внутреннем свойстве [[scope]]), который ассоциирован с каждой функцией. Т.е. схематически [[scope]] функции test будет таким:

[[scope]](test) = {
  VO(Global): {
    a: 10
  },
  VO(test): {
    c: 20;
  }
};


А далее - самое интересное (опять же - смотреть в 10.1.4). При обращении к переменной внутри функции она ищется в скоп-чейне последовательно вверх, начиная от VO самой функции. Все. Больше никаких чудес нет.

Поэтому ясно видно, что: alert(c); сработает быстрее, т.к. свойство "c" будет сразу же найдено в первом просматриваемом скопе.

Что же касается alert(a):

- смотрим в VO(test); - не нашли;
- смотрим в VO(Global) - нашли.

Два действия против одного (поиск в двух скопах (обращение к глобальной переменной) против моментального нахождения в первом скопе (обращение к локальной переменной)). Есть разница? Ну вот и замечательно.

Поэтому, еще раз - обращение из абстрактного локального скопа к глобальной переменной всегда (всегда!) будет медленней, чем обращение к локальной. Точка.

P.S.: VO(Global) - это утрированно, на самом деле сам Global уже является variable object'ом для глобальных переменных.

P.S.[2]: еще раз (уже зная теорию) смотрите результаты своего же примера:

<html>
<body>
<script type="text/javascript">

// local var
function F1(){
  var arr = [];
  // здесь идет обращение к *локальной* переменной
  // arr
  for (var i=0;i<1000;i++) arr.push(i);
}

var start = new Date();
for (var i=0;i<1000;i++) F1();
var res1 = (new Date())-start;
//**********************************


// Global var

function F2(){
  for (var i=0;i<1000;i++) arr.push(i);
}

var start = new Date();
var arr = [];
for (var i=0;i<1000;i++) F2();
var res2 = (new Date())-start;

// test 3

var start = new Date();
var arr2 = [];
for (var i=0;i<1000;i++) {
  for (var k=0;k<1000;k++) arr.push(k);
}
var res3 = (new Date())-start;

//**********************************


alert([res1, res2, res3]);

</script>
</body>
</html>


P.S.[3]: ZoNT, я пока закрываю глаза на все твои переходы на личности (в надежде, что мои подробные разъяснения помогут тебе более детально понять, как работает JavaScript), но это последнее предупреждение. Общаться - давай общаться, но рассуждать тут о нубстве и о возрастах, когда ты сам не далеко ушел от нубства в данном конкретном вопросе - это излишне.

P.S.[4]: а по поводу выделения памяти каждый раз (вместо уже существующей - не важно - в глобальном контексте, или же в прототипе конструктора, как я отмечал) - это уже другой вопрос совсем. И не зачем подменять понятия, говоря, что работает быстрее - "обращение к локальной или глобальной переменной?". Я и сам отметил (о хранении однотипного объекта в одном месте).

Андрей Параничев 11.08.2008 01:52

Dmitry A. Soshnikov,
На самом деле тут все просто. Ты говоришь: код функции будет всегда быстрее работать с локальной переменной, чем с глобальной. Это очевидно. Он говорит: не любой скрипт, где неоднократно вызывается функция использующая локальные переменные, будет работать быстрее, чем тот, в котором функция использует глобальные переменные. И приводит в пример код топикстартера. Тут чисто дурацкие придирки к формулировкам.

Тем не менее на вопрос
Цитата:

Сообщение от Бухалыч
Разве функция работает не быстрей, если обращается к локальным переменным?

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

Бухалыч 11.08.2008 09:31

Спасибо за познавательную дискуссию!
Изначально я делал переменные для многократно вызываемых функций глобальными, потом решил посмотреть, что будет в случае локальных.
Так вот, во втором случае в ФФ и Опере тормозить стало меньше, ну а ИЕ - по барабану.
Дело, наверно, в том, что функция обращается к переменным не 1 раз, а 4

ZoNT 11.08.2008 09:33

функция F1 работает медленне (с локальной переменной а) чем F2, так как ей приходится инициализировать свою переменную локально...

Никаких "скрипт".

Dmitry A. Soshnikov 11.08.2008 11:54

ZoNT, ну так и надо говорить о работе каких-то там функций, а не об "обращении к локальным и глобальным переменным".

Цитата:

Сообщение от ZoNT
функция F1 работает медленне (с локальной переменной а) чем F2

ну не правда - смотри результаты.

Цитата:

Сообщение от ZoNT
так как ей приходится инициализировать свою переменную локально

неверный логический вывод, эта инициализация может пройти намного быстрей, чем обращение к глобальной переменной (что и показывает пример - функция F1 работает быстрей F2)

Бухалыч 11.08.2008 13:24

Залил с глобальными. Что-то разницы не видно

ZoNT 11.08.2008 14:18

А разницу в размере скрипта не увидел???

Андрей Параничев 11.08.2008 14:49

Цитата:

Сообщение от ZoNT
функция F1 работает медленне (с локальной переменной а) чем F2, так как ей приходится инициализировать свою переменную локально

Какой смысл на эту тему спорить дальше? Повторяйте выполнять примеры кода из этой темы до полного понимания.

Бухалыч 11.08.2008 18:53

Вложений: 1
Если интересно, вот тест с локальными/глобальными
(там пробег по всем элементам)

Гость 16.08.2008 13:29

Мне очень интересно узнать две вещи.
Во первых объясните пожалуйста с какой целью http://chem.50webs.com/mendeleev/table.html генерируется полностью Ява скриптом.
Во вторых http://chem.50webs.com/mendeleev/table.html использует кодировку UTF-8 и все символы прекрасно отображаются. Но стоит мне своей страничке выставить charset=UTF-8 как напроч перестают отображатся все русские буквы. Вместо них абракадабра. Приходится использовать windows-1251. С чем это связано?
P.S. http://chem.50webs.com/mendeleev/table.html Мне очень понравился, появилось желание сверстать нечто подобное.


Часовой пояс GMT +3, время: 03:30.