Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как после компиляции выглядят ссылки на свойства (http://www.flasher.ru/forum/showthread.php?t=207326)

Akopalipsis 09.04.2014 17:07

Как после компиляции выглядят ссылки на свойства
 
Всегда думал, что если в цикле обращаться к свойству композитносозданного объекта,
то лучше это значение сохранить в локальную переменную. Думал, что обратится к локальной переменной быстрее, чем к свойству, путь к которому состоит из нескольких ссылок.
А начал проверять и все оказалось наоборот.
Вот результаты при чтении -
Код AS3:

 package 
{
        import flash.display.Sprite;
        import flash.utils.getTimer;
        public class TestSpeed4 extends Sprite
        {
                public function TestSpeed4()
                {
                        var array:Array = [];
                        for (var i:int = 0; i < 500; i++)
                        {
                                array[i] = 0;
                        }
                        var value:ValueClass = new ValueClass();
                        var boolean:Boolean;
                        var valueValue:int = value.value;
                        for (var j:int = 0; j < 100000; j++)
                        {
                                var length:int = array.length;
                                while (length--)
                                {
                                        boolean = array[length] > value.value;// 12 000
                                        boolean = array[length] > valueValue;// 13 000
                                }
                        }
 
                        time = testSpeed();
                        trace(time-now, now);
                }
 
                private var time:Number = 0;
                private var now:Number = 0;
                private function testSpeed():Number
                {
                        return getTimer();
                }
 
        }
 
}

А вот при записи ( тут я даже локальную переменную не присваивал свойству другого объекта,а то разница и была бы опять в секунду ) -
Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.utils.getTimer;
        public class TestSpeed4 extends Sprite
        {
                public function TestSpeed4()
                {
 
                        var value:ValueClass = new ValueClass();
                        var valueValue:int = value.value;
                        for (var j:int = 0; j < 100000; j++)
                        {
                                var length:int = 500;
                                while (length--)
                                {
                                        value.value += 1;// 11 000
                                        valueValue += 1;// 11 100;
                                }
                        }
 
                        time = testSpeed();
                        trace(time-now, now);
                }
 
                private var time:Number = 0;
                private var now:Number = 0;
                private var _target:Sprite;
                private function testSpeed():Number
                {
                        return getTimer();
                }
 
        }
 
}

Не уверен в правильности вопроса, но - как после компиляции, выглядит ссылки на свойства других объектов, если операции с локальными свойствами занимают больше времени?

samana 09.04.2014 17:40

Я не совсем по теме, но мне бросилось в глаза то, что тест вы проводите в конструкторе и скорее всего в дебагплеере, а это совсем неправильный подход.

Akopalipsis 09.04.2014 17:44

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

samana 09.04.2014 18:00

Нужно просто делать в релиз плеере (результаты например выводить в текстовое поле). Время засекаете перед началом теста (в начале метода например или цикла), а не при создании свойства. И желательно тест проводить не один раз при запуске, а на enterFrame. И посмотреть средний результат.

Akopalipsis 09.04.2014 19:00

Сделал так -
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.TimerEvent;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.utils.Timer;
 
 
        public class Main extends Sprite
        {
                private var textField:TextField;
                private var speedTest:TestSpeed;
                private var timer:Timer;
                private var num:int;
                public function Main()
                {
                        speedTest = new TestSpeed(print);
 
                        timer = new Timer(2, 1);
                        timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);
                        timer.start();
                }
 
                private function timer_timerCompleteHandler(event:TimerEvent):void
                {
                        for (var i:int = 0; i < 1000; i++)
                        {
                                num += 1;
                        }
 
                        speedTest.execute();
                }
 
                private var offsetY:int;
                private var allRepetitions:int = 5;
                private var repetitionsPerformed:int;
                private function print():void
                {
                        textField = new TextField();
                        textField.autoSize = TextFieldAutoSize.LEFT;
                        super.addChild(textField);
                        textField.text = "Кол-во выполений - " + ++repetitionsPerformed + " из " + allRepetitions + ", время выполнения - " + speedTest.runtime + ".";
                        textField.y = offsetY += 30;
 
                        if (repetitionsPerformed != allRepetitions)
                                        timer.start();
                }
        }
 
}

Код AS3:

package
{
        import flash.utils.getTimer;
        public class TestSpeed
        {
                private var time:Number = 0;
                public var runtime:Number;
                private var callback:Function;
 
                public function TestSpeed(callback:Function)
                {
                        this.callback = callback;
                }
 
                public function execute():void
                {
                        var value:ValueClass = new ValueClass();
                        var valueValue:int = value.value;
 
                        runtime = 0;
                        time = getTimer();
                        for (var j:int = 0; j < 1000000; j++)
                        {
                                var length:int = 500;
                                while (length--)
                                {
                                        ///
                                }
                        }
                        runtime = getTimer() - time;
 
                        this.callback();
                }
        }
 
}

На "присвоить значение" - 5350 локальная переменная, против 5000 свойства объекта.
На "получить значение" - 5900 против 5000...

dimarik 09.04.2014 21:18

Вот это номер! Нужно срочно Джексондунстану сказать.

silin 09.04.2014 21:21

>> На "присвоить значение" - 5350 локальная переменная, против 5000 свойства объекта.

померяй время 'пустого' цикла и будешь неожиданно удивлен, что эти 5000 ( а может случится, что и большеЖ) на него и уходят..
я не знаю наверное, но полагаю, что сегодняшние версии плеера достаточно оптимизированы для доступа к полям объектов, чтобы вручную здесь что-то выгадывать
естественно, это не касается доступа к динамическим свойствам и акцессорам - там время на порядок больше и в этом случае сохранять в локальной переменной есть смысл

Akopalipsis 09.04.2014 21:41

Сделал тест на ентерфраме и всё вроде бы встало на свои места.
Чтение показывает одинаковое время, а запись вот в таком виде, даже вредит,
что склоняет к правоте silin'a.
И хочется ещё уточнить, какой из всех вариантов замера, по Вашему самый лучший, если он тут вообще есть?
Код AS3:

var value:ValueClass = new ValueClass();
var valueValue:int = value.value;
var num:int;
runtime = 0;
time = getTimer();
for (var j:int = 0; j < 100000; j++)
{
        var length:int = 500;
        while (length--)
        {
                valueValue +=1;// 5 000;
        }
        value.value = valueValue;
}

Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.TimerEvent;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.utils.Timer;
 
 
        public class Main extends Sprite
        {
                private var textField:TextField;
                private var speedTest:TestSpeed;
                private var timer:Timer;
                private var num:int;
                public function Main()
                {
                        speedTest = new TestSpeed(print);
 
                        textField = new TextField();
                        timer = new Timer(2, 1);
                        timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);
                        timer.start();
                }
 
                private function timer_timerCompleteHandler(event:TimerEvent):void
                {
                        timer.removeEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);
                        timer = null;
 
                        stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
                }
 
                private var frameSun:int;
                private var totalFrame:int = 120;
                private var delayFrame:int = 240;
                private function stage_enterFrameHandler(event:Event):void
                {
                        if (delayFrame > -1)
                        {
                                delayFrame--;
                                return;
                        }
                        if (frameSun++ < totalFrame)
                                        speedTest.execute();
                }
 
                private var offsetY:int;
                private function print():void
                {
                        textField.autoSize = TextFieldAutoSize.LEFT;
                        super.addChild(textField);
                        textField.text = "Кол-во выполений - " + frameSun + " из " + totalFrame + ", время выполнения - " + speedTest.runtime + ".";
                }
        }
}


silin 09.04.2014 22:06

>>хочется ещё уточнить, какой из всех вариантов замера, по Вашему самый лучший

по мне так самый лучший это самый понятный, ну типа в цикле то, что интересует и все.
а эти штуки с while внутри for или new TestSpeed(print) и прочие таймеры я что-то не могу разгадать

Добавлено через 3 минуты
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.utils.getTimer;
 
 
        public class Main extends Sprite
        {
 
                public function Main()
                {
 
                        tf.autoSize = TextFieldAutoSize.LEFT;
                        addChild(tf);
                        tf.appendText("write:");
                        writeTest();
                        tf.appendText("read:");
                        readTest();
                }
 
                private const N:int = 5e7;
                private var memberProp:int;
                private static var staticProp:int
                private var tf:TextField = new TextField();
 
 
 
                private function writeTest():void
                {
 
                        var i:int;
                        var t:Number;
                        var localProp:int=0;
                        var obj:ValueClass = new ValueClass();
 
                        for (i = 0, t = getTimer(); i < N; i++);
                        tf.appendText( "\nloopTime : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) memberProp = 0;
                        tf.appendText( "\nmemberProp : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) localProp = 0;
                        tf.appendText( "\nlocalProp : " +  (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) staticProp = 0;
                        tf.appendText( "\nstaticProp : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.value = 0;
                        tf.appendText( "\nobjProp : " + (getTimer() - t) );
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.prop = 0;
                        tf.appendText( "\ndynamicProp : " + (getTimer() - t) );
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.accessor = 0;
                        tf.appendText( "\naccessProp : " + (getTimer() - t) );
 
                        tf.appendText("\n")
 
                }
 
                private function readTest():void
                {
 
                        var i:int;
                        var t:Number;
                        var localProp:int=0;
                        var obj:ValueClass = new ValueClass();
                        obj.prop = 0;
 
                        for (i = 0, t = getTimer(); i < N; i++);
                        tf.appendText( "\nloopTime : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) memberProp;
                        tf.appendText( "\nmemberProp : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) localProp;
                        tf.appendText( "\nlocalProp : " +  (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) staticProp;
                        tf.appendText( "\nstaticProp : " + (getTimer() - t));
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.value;
                        tf.appendText( "\nobjProp : " + (getTimer() - t) );
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.prop;
                        tf.appendText( "\ndynamicProp : " + (getTimer() - t) );
 
                        for (i = 0, t = getTimer(); i < N; i++) obj.accessor;
                        tf.appendText( "\naccessProp : " + (getTimer() - t) );
 
                        tf.appendText("\n")
 
                }
 
        }
 
}
////////
dynamic class ValueClass
{
        public var value:int = 0;
        private var _value:int = 0;
 
        public function get accessor():int
        {
                return _value;
        }
 
        public function set accessor(value:int):void
        {
                _value = value;
        }
 
 
}


Akopalipsis 09.04.2014 22:46

TestSpeed это класс, где скорость и замеряется, я его в отдельный вынес класс вынес и поставил таймер, только для того, чтобы дать плееру, как следует запустится. Если делаю, как в первом примере, то и разница такая же. А цикл в цикле сделал, потому что читал где-то про разницу работы кода в зависимости от кол-ва итераций. Типа, один и тот же код будет медленнее работать при 100 итераций и быстрее при 1 000 000. Но я тестирую код, который миллион не когда не увидит и хотелось бы точнее уточнить, как он на малых кол-вах итераций работает. Вот и пришлось цикл в цикле делать. А скаут, разницы во времени такую мизерную, как-будто не замечает, а я именно за неё и борюсь.

Код AS3:

package 
{
        import flash.utils.getTimer;
        public class TestSpeed
        {
                private var time:Number = 0;
                public var runtime:Number;
                private var callback:Function;
 
                public function TestSpeed(callback:Function)
                {
                        this.callback = callback;
                }
 
                public function execute():void
                {
                        var value:ValueClass = new ValueClass();
                        var valueValue:int = value.value;
                        var num:int;
                        runtime = 0;
                        time = getTimer();
                        for (var j:int = 0; j < 1000; j++)
                        {
                                var length:int = 500;
                                while (length--)
                                {
                                        value.value +=1;
                                }
                        }
                        runtime = getTimer() - time;
 
                        this.callback();
                }
        }
 
}


alexcon314 09.04.2014 22:57

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

Не нужно иметь семи пядей во лбу и перечитать пол-интернета, чтобы понять элементарную вещь: обращение к свойсву объекта осуществляется через оператор "." (точка), к локальной переменной обращение идет напрямую. Что быстрее?

silin 09.04.2014 23:39

>>А скаут, разницы во времени такую мизерную, как-будто не замечает, а я именно за неё и борюсь.

ну ясно, серьезный подход, прогрев плеера, вариативность циклов, внушает..
но, если простейший тест на милионах итераций показывает разницу, сопоставимую с точностью системного таймера, у меня, например, нет никаких сомнений, что ловить здесь нечего
и еще не надо забывать, что на другом железе\ОС\плеере ситуация может оказаться совсем другой, вплоть до противоположной

>>обращение к свойсву объекта осуществляется через оператор "." (точка), к локальной переменной обращение идет напрямую. Что быстрее?

вроде бы напрямую должно быть быстрее, но почему-то тест (пост №9) этого не показывает
а в стародавние времена, бывало показывал.. Ж)
я склонен думать, что плеер научили это делать самому, а может и всегда так было и это миф такой..

Akopalipsis 09.04.2014 23:49

Цитата:

и гордо объявить во всеуслышание
Возможно это Вы вспоминаете свои чувства, которые испытывали при написании статей в блоге?
Не буду говорить за всех, я не такой! Мне гордо заявлять, даже если бы и было, то я это сделал по скромному:D По этому мне даже смешно, когда на меня то троля нацепить хотят, то гордого заявляющего,
то ещё чего-то. Из-за Вас я вообще уже боюсь темы создавать на форуме, и создавая их, уже трясусь от мыслей, что мой бан зависит от какой-то магнитной бури.
Соорудил я к ней тест... да, но еслиб молчал, то во первых, так бы и пользовался нелепым тестом, а во вторых, если даже я делаю тест в релизе и без энтерфрейм, то результаты, как в самом начале.
А что быстрее, я же вроде написал, что был уверен до сегодняшнего момента, что быстрее локальная.

один из многих -
Код AS3:

write:
loopTime : 536
memberProp : 597
localProp : 594
staticProp : 700
objProp : 590
dynamicProp : 6061
accessProp : 6414
read:
loopTime : 505
memberProp : 502
localProp : 500
staticProp : 515
objProp : 495
dynamicProp : 3949
accessProp : 5813

а иногда бывает вот так -
Код AS3:

write:
loopTime : 524
memberProp : 562
localProp : 552
staticProp : 665
objProp : 570
dynamicProp : 5682
accessProp : 5951
read:
loopTime : 494
memberProp : 503
localProp : 490
staticProp : 522
objProp : 500
dynamicProp : 4083
accessProp : 5871

Добавлено через 2 минуты
И вот при таком раскладе, проще всего забыть о сохранении значения в локальную переменную,
хотя бы при одной точки. И вот такие результаты через раз, то больше, то меньше.

Добавлено через 5 минут
Только хотел уже закрыть этот класс, но думаю дай ещё раз нажму с закрытым браузером, в котором флеш плеер с музыкой ( хоть и выключена )...
Код AS3:

write:
loopTime : 500
memberProp : 572
localProp : 590
staticProp : 680
objProp : 570
dynamicProp : 6075
accessProp : 6008
read:
loopTime : 490
memberProp : 523
localProp : 482
staticProp : 510
objProp : 480
dynamicProp : 4091
accessProp : 5813

Добавлено через 31 секунду
Наверное я такой глупый, что надо мной даже плеер смеется:D

Добавлено через 11 минут
И такие результаты даже если сделать класс из примера silin'a не динамическим ( это я уже на всякий случай попробовал, так-как не знаю как себя ведёт класс помеченный dynamic ). И ещё что бросается в глаза, что если разница есть с записью, то разница при чтении почти не когда не бывает в пользу локальных переменных.

ChuwY 10.04.2014 05:09

А можно еще разок прогнать релиз-билд недебаговым плеером.

alexcon314 10.04.2014 08:42

Ну, вот заставь Akopalipsis'a б-гу молиться... весь лоб расшибет.
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.TimerEvent;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.utils.getTimer;
        import flash.utils.Timer;
 
 
        public class Main extends Sprite
        {
                private const N:int = 5e7;
                private const D:int = 5000;
                private const C:int = 100;
                private var timer:Timer;
                private var memberProp:int;
                private static var staticProp:int
                private var tf:TextField = new TextField();
                private var member_store:int = 0;
                private var local_store:int = 0;
                private var static_store:int = 0;
 
                public function Main()
                {
                        tf.autoSize = TextFieldAutoSize.LEFT;
                        addChild(tf);
                        timer = new Timer(D, C);
                        timer.addEventListener(TimerEvent.TIMER, test);
                        timer.addEventListener(TimerEvent.TIMER_COMPLETE, result);
                        timer.start();
                }
 
                private function result(e:TimerEvent):void {       
                        tf.appendText( "\nmemberProp (avg): " + member_store / C);
                        tf.appendText( "\nlocalProp (avg) : " + local_store / C);
                        tf.appendText( "\nstaticProp (avg) : " + static_store / C);
                        timer.stop();
                }
                private function test(e:TimerEvent):void
                {       
                        tf.text = "Current tick: " + timer.currentCount;
                        //writeTest();                       
                        //readTest();
                        /*
                        * нужный тест раскомментровать
                        * скомпилировать
                        * запустить
                        */

                }
 
                private function writeTest():void
                {
 
                        var i:int;
                        var t:Number;
                        var localProp:int=0;
 
                        for (i = 0, t = getTimer(); i < N; i++) memberProp = 0;
                        member_store += (getTimer() - t);
 
                        for (i = 0, t = getTimer(); i < N; i++) localProp = 0;
                        local_store += (getTimer() - t);
 
                        for (i = 0, t = getTimer(); i < N; i++) staticProp = 0;
                        static_store += (getTimer() - t);
                }
 
                private function readTest():void
                {
 
                        var i:int;
                        var t:Number;
                        var localProp:int = 0;
 
                        for (i = 0, t = getTimer(); i < N; i++) memberProp;
                        member_store += (getTimer() - t);
 
                        for (i = 0, t = getTimer(); i < N; i++) localProp;
                        local_store += (getTimer() - t);
 
                        for (i = 0, t = getTimer(); i < N; i++) staticProp;
                        static_store += (getTimer() - t);
 
                }
        }
}

Цитата:

//FP 11.7 release
//Flex 4.6 FD 4.4.3
//Build: Release
//Win 7 Pro x64 Core i3 6Gb
//N = 5e7, D = 5000, C = 100

//readTest()
Current tick: 100
memberProp (avg) : 124.62
localProp (avg) : 105.01
staticProp (avg) : 103.94

//writeTest()
Current tick: 100
memberProp (avg) : 132.95
localProp (avg) : 107.54
staticProp (avg) : 254.19
Физкульт-привет "некогданам"!


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

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