Форум 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();
                }
        }
 
}



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

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