Flash - статьи



              

Немного оптимизации: истребляем в себе все человеческое - часть 2


Короче, мы должны будем отслеживать, как наша "стрелка часов" приближается к нулевой отметке, и брать, например, первую точку, которая прошла "за полночь". Не точно, не удобно и не спортивно. Гораздо проще и куда интереснее разделить нашу революцию на целое число частей (как это сделано с градусами) и "ходить конем" только в эти точки. Тогда вычисления аттрактора будут точными, кратными целому и постоянному числу "ходов".

На сколько частей делить революцию — априори не понятно, но можно предположить, что для вычислений удобными будут степени двойки. Тогда мы сможем для энного хода получать значение mod(n), что для степеней двойки эффективно реализуется отбрасыванием старших разрядов с помощью битовой операции AND.

Введем такую величину, как революция/2n, или сокращенно revN2. Это величина, представляющая деление одного оборота на 2n. То есть: rev8 — 256-я часть от одного оборота, rev10 — 1024-я и т.д. Такая система измерения удобна для компьютера. Например, можно создать объект rev (8, "сos", R, w), который просчитывает косинус с градацией 256 позиций на один оборот, с радиусом R и частотой w и заносит результаты в таблицу-массив. Частота тут, собственно, нужна, для вычисления временного шага: если rev8=2*Pi/2n, то w*dt_revN=2*Pi/2n, в частности w*dt_rev0=2*Pi/20. Это можно реализовать как метод объекта rev, например GetTimeStep().

Теперь все чудно: для получения тысячи точек аттрактора только и нужно, что устроить цикл:

for (i=0;i++;i<1000) for (j=0;j++;j<256)

А значения косинуса можно получать из массива в заранее просчитанном объекте rev:

rev.GetValue(i)

Не буду рассказывать, насколько выборка из массива быстрее вычисления косинуса. Скажу только, что в ActiveScript обе операции реализованы способом, далеким от идеального. Массивы на самом деле представляют собой ассоциативные списки Java, косинус — тоже, очевидно, не реализуется одной процессорной командой, как могло бы быть в идеале. Но и в этом случае массив дает огромное преимущество, включая экономию на одном дополнительном умножении на радиус на каждом расчете. Ситуация осложняется еще и тем, что для расчета одной точки Cos вызывается четыре раза, то есть для тысячи точек и rev8 количество вычисляемых косинусов достигает 4х256х1000=1e6, то есть одного миллиона! Это не шутка даже для ассемблера.

На этом — конец теории, полный и окончательный.




Содержание  Назад  Вперед