Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript (http://www.flasher.ru/forum/forumdisplay.php?f=5)
-   -   Занимательный ActionScript ('for' <--> 'while') (http://www.flasher.ru/forum/showthread.php?t=34226)

Suhoff 10.07.2002 03:38

Занимательный ActionScript ('for' <--> 'while')
 
По мере продолжения изучения грамматики AS, у меня возник вопрос - а зачем, собственно, нужна инструкция for (но не for(... in ...) - с ней понятно), если всё, что можно сделать с помощью этой инструкции можно сделать и с помощью инструкции while?
Смотрим определения в ECMA-262:

IterationStatement : See 12.6
................................................................
while ( Expression ) Statement
for (ExpressionNoIn(opt); Expression(opt) ; Expression(opt) ) Statment
......................1.........................2......................3......................
................................................................................................
(opt) означает, что это выражение -Expression, можно опустить.

/Выражение 1/ выполняется один раз при инициализации инструкции for, поэтому его можно вынести из этой инструкции -

ExpressionNoIn(opt);for (; Expression(opt) ; Expression(opt) ) Statement
..................1................................2................................3......................

/Выражение 3/ выполняется только тогда, когда выражение 2 имеет значение true, поэтому его тоже можно вынести из инструкции и записать в эквивалентном виде -

ExpressionNoIn(opt);for (; Expression(opt) ; ) {Expression(opt);Statement};
..................1................................2................................3.................
a <for (; Expression(opt) ; )>- это в чистом виде <while ( Expression )> (если имеем <for(;;)> то тогда <while(true)>).

Спрашивается - зачем плодить лишние инструкции?????
Или я ошибаюсь???

Кстати замечаем, что везде в определении инструкций for и while используются Expression. Смотрим определение для Expression:

Expression : See 11.14
AssignmentExpression
Expression , AssignmentExpression

те Expression - это любое конечное количество AssignmentExpression разделённых запятой!!
Например: s=f,v>>k,c<d - это Expression,
и a=(b=1+1,2+2) - это тоже Expression
причём для вычисления ЗНАЧЕНИЯ Expression берётся ПОСЛЕДНЕЕ AssignmentExpression!! (в примере a=4,b=2);

Это в некоторых случаях можно использовать в вычислениях.
Рассмотрим вычисление факториала числа N в стандартном представлении с помощью цикла for:
(для конкретности N=10)
1)
.......
N=1;
for (var i=1;i<=10;i++) N*=i;
.......
А теперь запишем то же самое с помощью цикла while

2) N=i=1;while(N*=i,++i<=10);

так вот - второй вариант на моём компе выполняется на 20% быстрее, чем первый!!!

Впрочем, можно записать вычисления факториала и третьем варианте -

3) for (N=i=1;N*=i,++i<=10;);

причём скорость вычисления 3-го варианта очень близка к скорости вычисления 2-го. По-видимому 3 и 2 транслируются в один и тот же код.
Кстати, варианты 2 и 3 вызывают, по крайней мере у SWFscaner'a, лёгкую истерику - понять, что же делается в раскодированной инструции совершенно невозможно.
Это тоже , я думаю, можно использовать ;).

PS. Возможно это всё уже давным давно известно, и я изобретаю велосипед, но мне было бы интересно выслушать мнение флашеров по этому поводу.

CyberMax 10.07.2002 05:28

Цитата:

По мере продолжения изучения грамматики AS, у меня возник вопрос - а зачем, собственно, нужна инструкция for (но не for(... in ...) - с ней понятно), если всё, что можно сделать с помощью этой инструкции можно сделать и с помощью инструкции while?
Утверждают, что ЛЮБОЙ алгоритм можно записать при помощи if-ов и goto. Но зачем-то всякие ООП понапридумывали ;)
Просто иногда программисту удобнее написать for, а не while. Главное -- удобства для разработчика, а пользователи пусть идут лесом ;)

Когда разрабатывали ECMA-262 Flash еще не поддерживал этот стандарт.
Синтаксис ECMA-262 во многом базируется на синтаксисе Cи, а там такой вариант есть.
Flash при трансляции ActionScripta в байткод не проводит НИКАКОЙ оптимизации. Так что тот факт, что одна конструкция работает дольше, чем другая ни о чем еще не говорит.
А какой код генерирует Flash для той или иной конструкции можно посмотреть Flasm`ом.

Цитата:

Спрашивается - зачем плодить лишние инструкции?????
Или я ошибаюсь???
А Flash тут при чем ? Коль скоро такая языковая конструкция описана в стандарте значит нужно ее поддерживать. Тебе не нужно -- не пользуйся.

Royan 11.07.2002 21:12

Вот тут CyberMax утверждает, что трансляционный код flesh'a не проводит ни какой оптимизации с чем я не соглашусь. Ради примера можно рассмтреть AS приведенный во втором и третьем пунктах (повторю его здесь)


for (N=i=1; N*=i,++i<=10; ) {
}
var N=i=1;
while (N*=i,++i<=10) {
}
И теперь можно посмотреть как именно раскрывают сей код всякие там ASV
N = (i = 1);
(N = N * i);
while (++i <= 10) {
}
var N = (i = 1);
(N = N * i);
while (++i <= 10) {
}
Сразу замечу, что если написать в Flash 5,0,0,0 (я его качал почти сразу как он вышел) то такая вот конструкция цикла for: "for (N=i=1; N*=i,++i<=10; );" при перчлючении из режима expert в normal у меня вызывала критическую ошибку. В MX все было исправлено. Впрочем кому интересно тот может набрать собственный код, состоящий из каких угодно циклов for и убедиться, что любой сканер при разборе все переворачиват в while

И последняя ремарка, которую Sukoff не пояснил с точки зрения программирования на "С" подобных язяках

Цитата:

причём для вычисления ЗНАЧЕНИЯ Expression берётся ПОСЛЕДНЕЕ
дело в том, что символ запятая тоже является оператором и если мы запишим
a=0,1,2,3,4,5,6,7,8,9
то a==9
и соответственно, в приведенном Sukoff'ым примере допущена неточность
a=(b=1+1,2+2)

где a==4 и b==4 тоже!

CyberMax 11.07.2002 23:13

Цитата:

Оригинал написал(а) Royan
Вот тут CyberMax утверждает, что трансляционный код flesh'a не проводит ни какой оптимизации с чем я не соглашусь.
А чего тут не соглашаться-то ? Одни двойные отрицания чего стоят. Не вериш -- посмотри какой-нибудь SWF flasm`ом.
Цитата:

Ради примера можно рассмтреть AS приведенный во втором и третьем пунктах (повторю его здесь)


for (N=i=1; N*=i,++i<=10; ) {
}
var N=i=1;
while (N*=i,++i<=10) {
}
И теперь можно посмотреть как именно раскрывают сей код всякие там ASV
N = (i = 1);
(N = N * i);
while (++i <= 10) {
}
var N = (i = 1);
(N = N * i);
while (++i <= 10) {
}
Сразу замечу, что если написать в Flash 5,0,0,0 (я его качал почти сразу как он вышел) то такая вот конструкция цикла for: "for (N=i=1; N*=i,++i<=10; );" при перчлючении из режима expert в normal у меня вызывала критическую ошибку. В MX все было исправлено. Впрочем кому интересно тот может набрать собственный код, состоящий из каких угодно циклов for и убедиться, что любой сканер при разборе все переворачиват в while

Ну так это вовсе не говорит о том, что Flash циклы оптимизирует. Это говорит всего лиш о том, что автору ASV лень было заморачиваться с for-ами и он все циклы декомпилирует во while-циклы. В байткоде for от while не сильно отличается.

Nox Noctis 12.07.2002 01:36

Цитата:

Оригинал написал(а) Royan
дело в том, что символ запятая тоже является оператором и если мы запишим
a=0,1,2,3,4,5,6,7,8,9
то a==9
и соответственно, в приведенном Sukoff'ым примере допущена неточность
a=(b=1+1,2+2)

где a==4 и b==4 тоже!


а вот это - лажа, уважаемый :))

операторы записанные через запятую именно через запятую и выполняются - слева направо... это просто способ группировки - и больше ничего...
то есть:

a=0,1,2,3,4,5,6,7,8,9

эквивалентно :

a=0;
1;
2;
3;
......

значит 'а' будет равно 0
(ну и что что последующие инструкции (1;2;3; и т д) не несут смысловой нагрузки !)

а если написать:

a = (b=1+1, 2+2);

то это эквивалентно :

a = b = 1+1;
a = 2+2;


получаем a==4 и b==2
а все благодаря скобкам - если б мы написали
a = b=1+1, 2+2;
то получилибы в эквивалентном виде строки:
a = b = 1+1;
2+2;



так что.... :)))

Suhoff 14.07.2002 02:44

:)
... Судя по всему, я, действительно, изобрел велосипед.... :)
Об подобности <for> и <while> инструкций в языке С написано в книжке А.Ахо,Р.Сети,Д.Ульмана "Компиляторы. Принципы, технологии, инструменты." с.94... Так что похоже, что, действительно, при трансляции цикл <for> заменяется на эквивалентный цикл <while>...

Crazy 14.07.2002 03:07

Не заменяется при трансляции, а просто компилируется в аналогичный по структуре байткод. :)


Часовой пояс GMT +4, время: 11:21.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.