Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   увеличить глубину рекурсии (http://www.flasher.ru/forum/showthread.php?t=126799)

TanaTiX 27.06.2009 17:15

увеличить глубину рекурсии
 
Как увеличить глубину рекурсии? В качестве примера можно юзать такой код:
Код AS1/AS2:

j = 1000;
foo(0);
function foo(n) {
        if (n<j) {
                trace(n);
                foo(n+1);
        }
}

ЗЫ. циклы не предлагать - задачу специально максимально упростил.

iNils 27.06.2009 20:22

Цитата:

Сабж.
Так сложно сделать копипаст названия темы?

etc 27.06.2009 20:27

Прервать и продолжить?

TanaTiX 27.06.2009 21:30

Цитата:

Сообщение от iNils (Сообщение 831338)
Так сложно сделать копипаст названия темы?

Даже не знаю что ответить... Исправился.

Цитата:

Сообщение от __etc (Сообщение 831342)
Прервать и продолжить?

Как это можно осуществить к примеру на указанном примере? (пардон за тафтологию)
Что-то типа:
Код AS1/AS2:

j = 400;
foo(0);
function foo(n) {
        if (n<j) {
                trace(n);
                setTimeout(foo,0,n+1);
        }
}

Или есть более "правильные" способы?

etc 27.06.2009 21:48

Код AS1/AS2:

j = 400;
step = 0;
steps = 200;
foo(0);
function foo(n) {
        if (n<j) {
                step++;
                if (step > steps) {
                        setTimeout(foo,0,n+1);
                        step = 0;
                } else {
                        foo(n+1);
                }
        }
}

«Правильный» он тут может быть только в кавычках.

TanaTiX 28.06.2009 00:51

__etc, а какой смысл в проверке внутри функции глубины рекурсии? Ведь все равно рано или поздно придется применять задержку. Или с точки зрения работоспособности (или какой другой) это имеет смысл, не смотря на затрачиваемые на это ресурсы?

etc 28.06.2009 01:21

Смысл в преодолении лимита и всё.

DarkLight 28.06.2009 02:51

Глубина рекурсии байтом отдельным задается во флешке, в мануале к flasm (FLash ASseMbler) можно найти описание. Если очень хочется - делаем незапакованную свф, меняем байт, пакуем. А в CS4 уже в настройках публикации можно задавать. Но глубина рекурсии под 1000 это жесть, обычно можно написать эффективнее без нее.

TanaTiX 28.06.2009 13:17

DarkLight, я в цс4 искал, но что-то не нашел. Ткните, пожалуйста, носом невнимательного.
Flasm - интересная тема, надо почитать.

aksios 28.06.2009 14:32

Цитата:

Сообщение от DarkLight (Сообщение 831428)
А в CS4 уже в настройках публикации можно задавать.

Во Flex может? :)
Ваще автор, зачем Вам это?
Ваше творение при таком раскладе скушает все ресурсы, нужно делать, если что, хвостовую рекурсию и уходить с глубины всеми возможными способами.

etc 28.06.2009 20:08

DarkLight, ты не путаешь глубину рекурсии с настройками таймаута в CS4?

TanaTiX 29.06.2009 20:11

aksios, программу создаю, там реализовать рекурсией гораздо проще, чем циклами (как по мне, может и ошибаюсь). И вообще чем так плоха рекурсия?
Вот к примеру. Мне нужно обработать переменную в цикле относительно нескольких величин, т.е. по логике я должен создать цикл в цикле (а то и несколько ступеней вложенности) - флеш при этом однозначно повесится (возможно не на долго, но факт перегрузки есть), а в случае с использованием рекурсии все это решается более спокойно (хотя по времени может и дольше, но без подвисания компа). Вот и возникает вопрос: когда лучше рекурсия, а когда цикл?
Кстати, в моем примере достаточно сложная система обработки переменных, поэтому выбрал рекурсию (хотя наверное можно было бы попробовать и циклом).
Кстати о ресурсах - я частично уже написал, а если говорить о вышеуказанном коде, так там хоть 5000 итераций - субъективно будет практически без задержек.

DarkLight 29.06.2009 20:38

Цитата:

DarkLight, ты не путаешь глубину рекурсии с настройками таймаута в CS4?
хм, ну может быть, я давно не пользуюсь CS4, но в настройках, насколько помню, видел и то и другое. Возможно, привиделось)

Psycho Tiger 29.06.2009 21:32

Лучше тогда, когда это красивее выглядит, и более важно - быстрее бегает.
Кстати, а почему при рекурсии компьютер повеситься, а при циклах будет бегать быстрее?
Цитата:

а в случае с использованием рекурсии все это решается более спокойно (хотя по времени может и дольше, но без подвисания компа).
С чего это? Абсолютно одинаково.
Хотя, циклы пожалуй выйграют, ибо область поиска переменных у них будет более ближняя (они будут локальны) и будут быстрее обращаться, чем к функции, которая не локальна. Хотя, можно сделать на неё ссылку, но не факт, что поможет. Надо на досуге проверить)

TanaTiX 29.06.2009 22:22

Psycho Tiger и уважаемая публика...
Предлагаю 2 варианта кода, по сути делающих одно и то же: вывод мувика из библиотеки на основную сцену. В библиотеке мувик (просто квадрат) с Linkage "quad".
Код с применением цикла:
Код AS1/AS2:

Stage.align = "TL";
Stage.scaleMode = "noscale";
for (v=0; v<100; v++) {
        for (h=0; h<100; h++) {
                this.attachMovie("quad","quad_v"+v+"h"+h,this.getNextHighestDepth());
                this["quad_v"+v+"h"+h]._x = this["quad_v"+v+"h"+h]._width*v;
                this["quad_v"+v+"h"+h]._y = this["quad_v"+v+"h"+h]._height*h;
        }
}

Действительно работает быстрее, но на какое-то время полностью вырубает машину (может только мою =) )
Код с применением рекурсии (и задержки для обхода лимита ее глубину)
Код AS1/AS2:

Stage.align = "TL";
Stage.scaleMode = "noscale";
foo(0,0,this);
function foo(v, h, targ) {
        targ.attachMovie("quad","quad_v"+v+"h"+h,targ.getNextHighestDepth());
        targ["quad_v"+v+"h"+h]._x = targ["quad_v"+v+"h"+h]._width*h;
        targ["quad_v"+v+"h"+h]._y = targ["quad_v"+v+"h"+h]._height*v;
        if (h<100) {
                foo(v,h+1,targ);
        } else {
                if (v<100) {
                        setTimeout(foo,1,v+1,0,this);
                } else {
                        trace("stop");
                }
        }
}

Работает все же медленней (даже если задержку поставить в 0мс). Но при этом машина не зависает на несколько секунд, а результат можно лицезреть (это можно отнести как к плюсам, так и к минусам).
Исходя из вышесказанного остановлюсь все же на рекурсии (т.к. не думаю что пользователь будет рад полному подвисанию системы, даже в ущерб скорости). Если у кого будут другие мнения и/или доводы - с удовольствием выслушаю.

etc 29.06.2009 22:26

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

TanaTiX 30.06.2009 00:23

Цитата:

Сообщение от __etc (Сообщение 831826)
...не забивая память рекурсиями.

Т.е. получается любая функция хранится в памяти до окончания работы ролика , а рекурсия плодит их (функции) похлеще кроликов? Если да, то можно ли (и как) удалить рекурсивную функцию из памяти?

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

etc 30.06.2009 08:09

Память забивается стеком вызовов и локальными переменными, из значениями и областями видимости, очевидно же.

TanaTiX 03.07.2009 21:52

Всем спасибо за внимание, все понятно.

Upd. Вот стало интересно с Flasm-ом немного поиграться, интересно ж... Наваял такой незатейливый код:
Код AS1/AS2:

foo(0,200);
function foo(s, e) {
        this.txt.text += s+", ";//txt - InstanceName вручную созданного текстового поля
        if (s<e) {
                foo(s+1,e);
        }
}

После использования проги:
Код:

C:\Flasm>flasm -d rec.swf > rec.flm
В результате получаю такой код:
Код:

movie 'rec.swf' compressed // flash 9, total frames: 1, frame rate: 12 fps, 550x400 px

  frame 0
    constants 'txt', 'text', ', ', 'foo' 
    function2 foo (r:2='s', r:3='e') (r:1='this')
      push r:this, 'txt'
      getMember
      push 'text', r:this, 'txt'
      getMember
      push 'text'
      getMember
      push r:s, ', '
      add
      add
      setMember
      push r:s, r:e
      lessThan
      not
      branchIfTrue label1
      push r:e, r:s, 1
      add
      push 2, 'foo'
      callFunction
      pop
    label1:
    end // of function foo

    push 200, 0.0, 2, 'foo'
    callFunction
    pop
  end // of frame 0
end

Изменение значения с 200 на любое другое работает в пределах установленным по умолчанию, а где находится тот заветный кусок кода, в котором прописывается собственно ограничение на глубину рекурсии, для по прежнему остается загадкой. Поиск тоже не привел ни к чему путному (искал именно на счет рекурсии, в отношении оптимизации информация, хоть и мало, но есть). Если кто не против малость заморочиться (или просто знает) - спасибо.

ЗЫ. и я так понимаю, что под ас3 прога работать не будет?

Psycho Tiger 03.07.2009 23:34

Цитата:

Изменение значения с 200 на любое другое работает в пределах установленным по умолчанию
В смысле "не больше"? Может тип данных не позволяет выйти за большее?

etc 04.07.2009 10:39

Глубина рекурсии указана в теге ScriptLimits (65), максимум можно указать 65 535.

з. Ы. flasm с AS3 не работает.

TanaTiX 04.07.2009 13:21

Вопрос решен, все работает как надо, полет нормальный. Еще раз спасибо всем поучаствовавшим. Думаю, что тему можно считать закрытой.


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

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