AS3 optimization

Multiple ContextMenuItem for different objects

Posted in AS3 optimization, example, projects & snippets on August 11th, 2010 by admin – Be the first to comment

OK here is a simple way to create as many objects as you want context menus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;


function addContext(sprite_:Sprite):void {
    var menu:ContextMenu = new ContextMenu();
    menu.customItems = [new ContextMenuItem("Select only " + sprite_.name)];
    menu.hideBuiltInItems();
    sprite_.contextMenu = menu;
}

addContext(yellow);
addContext(green);
addContext(red);
addContext(blue);
addContext(this);

note that yellow, green, red, blue are Sprites, but it can be also buttons

Example:

This movie requires Flash Player 10

Nice post about The Right-Click Menu in Flash by Raiyan

Flash: How to prevent pop-up blocking in Firefox

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

Hi, I just want to point out some class that I find very useful. It help you no to block FF pop, when you call navigateToURL method. So here is the link:

Problems using navigateToURL

Here I will post the actionscript file, because when you copy it from the location it copies you also the numbers, which is kind of annoying.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.stanislavstankov.utils {
   
    import flash.external.ExternalInterface;
    import flash.net.URLRequest;
    import flash.net.navigateToURL;
   
    /**
     * Collection of URL util functions.
     *
     * ActionScript 3.0 / Flash 9
     *
     * @package    com.apdevblog.utils
     * @author     Philipp Kyeck / phil@apdevblog.com
     * @copyright  2008 apdevblog.com
     * @version    SVN: $Id: URLUtils.as 19 2008-04-08 09:57:50Z phil $
     *
     * based on script by
     * @author Sergey Kovalyov
     * @see http://skovalyov.blogspot.com/2007/01/how-to-prevent-pop-up-blocking-in.html
     *
     * and based on script by
     *
     * @author Jason the Saj
     * @see http://thesaj.wordpress.com/2008/02/12/the-nightmare-that-is-_blank-part-ii-help
     */

   
    public final class URLUtils {
       
       
       
        protected static const WINDOW_OPEN_FUNCTION:String = "window.open";
       
        /*------------------------------------
            Constructor
        ------------------------------------*/

        public function URLUtils():void {
        }
        /*------------------------------------
            Public methods
        ------------------------------------*/

       
       
        /**
         * Open a new browser window and prevent browser from blocking it.
         *
         * @param url        url to be opened
         * @param window     window target
         * @param features   additional features for window.open function
         */

       
        public static function openWindow(url:String, window:String = "_blank", features:String = ""):void {
            var browserName:String = getBrowserName();
            if (getBrowserName() == "Firefox") {
                ExternalInterface.call(WINDOW_OPEN_FUNCTION, url, window, features);
            } else if (browserName == "IE") {
                ExternalInterface.call("function setWMWindow() {window.open('" + url + "');}");
            } else if (browserName == "Safari") {
                navigateToURL(new URLRequest(url), window);
            } else if (browserName == "Opera") {
                navigateToURL(new URLRequest(url), window);
            } else {
                //Otherwise, use Flash's native 'navigateToURL()' function to pop-window.
                //This is necessary because Safari 3 no longer works with the above ExternalInterface work-a-round.
                navigateToURL(new URLRequest(url), window);
            }
        }
       
       
       
       
        /*------------------------------------
            Private methods
        ------------------------------------*/

        /**
         * return current browser name.
         */

         private static function getBrowserName():String {
             var browser:String;
             //Uses external interface to reach out to browser and grab browser useragent info.
             var browserAgent:String = ExternalInterface.call("function getBrowser(){return navigator.userAgent;}");
             //Determines brand of browser using a find index. If not found indexOf returns (-1).
             if (browserAgent != null && browserAgent.indexOf("Firefox") >= 0) {
                browser = "Firefox";
            } else if (browserAgent != null && browserAgent.indexOf("Safari") >= 0) {
                browser = "Safari";
            } else if (browserAgent != null && browserAgent.indexOf("MSIE") >= 0) {
                browser = "IE";
            } else if (browserAgent != null && browserAgent.indexOf("Opera") >= 0) {
                browser = "Opera";
            } else {
                browser = "Undefined";
            }
            return (browser);
        }
       
       
    }
}

I do not pretend in any way of that I write or have part of writing this class. Only distributing it :)

Array Function Class

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

This is class that I used often in my works :) Hope you find it useful. It manipulates Array Object. It is user to add or remove element from a certain position.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.stanislavstankov.shared.utils {
   
    public final class ArrayFunction {
       
        /*------------------------------------
            Public methods
        ------------------------------------*/

        /**
         * Remove element from an array.
         * @param selectedArr Array from whom will be remove element;
         * @param elementIndex Removed index from array. Firts item is with index = 0;
         * @return New array with removed element;
        */

        public static function removeElement(selectedArr:Array, elementIndex:int):Array {
            var outArr:Array = [];
            outArr = outArr.concat(selectedArr.slice(0, elementIndex), selectedArr.slice(elementIndex + 1));
            return outArr;
        }
       
        /**
         * Add element at index position in array. If given elementIndex is bigger or equal of the lenght of array, element is added like last element
         * @param selectedArr Array from whom will be remove element;
         * @param elementIndex Removed index from array. Firts item is with index = 0;
         * @param newObj Object that will be added;
         * @return New array with removed element;
        */

        public static function addElement(selectedArr:Array, elementIndex:int, newObj:Object):Array {
            var outArr:Array = [];
            outArr = outArr.concat(selectedArr.slice(0, elementIndex), newObj, selectedArr.slice(elementIndex));
            return outArr;
        }
       
    }
}

ActionScript 3 optimization techniques

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

hi all I have planned to start posting optimization techniques in couple of series. I will start first with showing you the techniques that Joa Ebert test work faster. Here you can find them

AS3. Optimization: int vs uint

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

Testing environment

You will find many tables that covers execution time. All this are done on machine:

Comp1
Intel(R) Core(TM) Duo CPU E8400 @ 3000Hz 3.00 GHz, 3 .00 GB of RAM with Windows XP Professional SP3, Flash player version 9.0.115.0, NOT DEBUG PLAYER

All the tests were not done using the debug player and they were not running in debug mode which is very important in specific cases. Each test case was running ten times. The result shown is always the average execution time of the ten runs. This way two tests do not conflict with the garbage collection and each test is just responsible for its own memory usage. Before each run there is a ten seconds delay in order to not conflict with the Flash player starting procedure.

From result that using uint and int in loop did not make time difference. But I suggest you use where you can int instead of uint. You can find interesting article about (int vs uint vs Number) this topics here:

Avoid ints in ActionScript, by Sho Kuwamoto, date: June 15th, 2006
Types in AS3: ints not so fast, uints slow!, by Grant Skinner, date: June 15th, 2006
Use the Correct Type for the Job, by Think, date: June 20th, 2006
Optimization: When to do it., by Keith Peters, date: June 21st, 2006

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package {
   
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.utils.setTimeout;
    import flash.system.Capabilities;
   
    [SWF(frameRate = '255')]
   
    public class TestCase extends Sprite {
        private static const n: int = 10000000;
       
       
        public function TestCase() {
            setTimeout(runTest, 10000);
        }
       
        private function runTest(): void {
            var a: Number = 0;
            for ( var i: int = 0; i < 10; ++i ) a += test06();
            a /= 10;
            showResults(a);
        }
       
        private function showResults(result_:Number):void {
            var result_txt:TextField = new TextField();
            result_txt.x = result_txt.y = 10;
            result_txt.width = 300;
            result_txt.text = "Iterations: [10^" + (String(n).length - 1) + "], int[ms]: " + result_ +"\nisDebugger: " + Capabilities.isDebugger + "\nversion: " + Capabilities.version;
            addChild(result_txt);
        }
       
       
        // 1. Iterations: [10^5], int[ms]: 4.7
        // 2. Iterations: [10^5], int[ms]: 5
        // 3. Iterations: [10^5], int[ms]: 4.4
        // 4. Iterations: [10^5], int[ms]: 4.7
        private function test00(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:int = 0; i < n; ++i ) {
                var a: Number = ( 1 as Number );
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^5], int[ms]: 5.4
        // 2. Iterations: [10^5], int[ms]: 5.2
        // 3. Iterations: [10^5], int[ms]: 5.2
        // 4. Iterations: [10^5], int[ms]: 5.4
        private function test01(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:uint = 0; i < n; ++i ) {
                var a: Number = ( 1 as Number );
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^7], int[ms]: 32.9
        // 2. Iterations: [10^7], int[ms]: 33.1
        // 3. Iterations: [10^7], int[ms]: 32.9
        // 4. Iterations: [10^7], int[ms]: 33.4
        private function test03(): int {
            var startTime:int = getTimer();
           
            //test start
            var k:uint;
            for (var i:int = 0; i < n; ++i ) {
                k++;
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
       
        // 1. Iterations: [10^7], int[ms]: 33
        // 2. Iterations: [10^7], int[ms]: 32.8
        // 3. Iterations: [10^7], int[ms]: 33
        // 4. Iterations: [10^7], int[ms]: 32.8
        private function test04(): int {
            var startTime:int = getTimer();
           
            //test start
            var k:int;
            for (var i:int = 0; i < n; ++i ) {
                k++;
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
       
        // 1. Iterations: [10^7], int[ms]: 91.8
        // 2. Iterations: [10^7], int[ms]: 91.8
        // 3. Iterations: [10^7], int[ms]: 91.7
        // 4. Iterations: [10^7], int[ms]: 91.8
        private function test05(): int {
            var startTime:int = getTimer();
           
            //test start
            var k:int;
            for (var i:int = 0; i < n; ++i ) {
                k = (i + 15) / 7;
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^7], int[ms]: 91.8
        // 2. Iterations: [10^7], int[ms]: 92.3
        // 3. Iterations: [10^7], int[ms]: 92.2
        // 4. Iterations: [10^7], int[ms]: 92.2
        private function test06(): int {
            var startTime:int = getTimer();
           
            //test start
            var k:uint;
            for (var i:int = 0; i < n; ++i ) {
                k = (i + 15) / 7;
            }
           
            //test end
            return (getTimer() - startTime);
        }
    }
}

AS3 Cross Plot

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

I had to create Cross plot for one of my university exam (of Computer Aided Geometric Design). Here is little more info. Note that source files are available ;)

Parametric Bezier curves are composed of coordinate functions: each component is a Bezier function. For two-dimensional curves, this can be used to construct the cross plot of curve. Image shows the decomposition of a Bezier curve into its two coordinate functions. A cross plot can be very helpful tool for the investigation not only of Bezier curves, but of general two-dimensional curves. We will use it for the analysis of Bezier and B-spline curves. It can be generalized to more then two dimensions, but is not as useful then.

Cross plot

Cross plot

You can see the example here.
Source files

info about program:

cross plot lines & symbols counter printscreen

cross plot lines & symbols counter printscreen

Printscreen:

cross plot printscreen

cross plot printscreen

AS3. Optimization: initializing Object and Array

Posted in AS3 optimization, actionscript 3 on June 16th, 2009 by admin – Comments Off

Testing environment

You will find many tables that covers execution time. All this are done on machine:

Comp1
Intel(R) Core(TM) Duo CPU E8400 @ 3000Hz 3.00 GHz, 3 .00 GB of RAM with Windows XP Professional SP3, Flash player version 9.0.115.0, NOT DEBUG PLAYER

All the tests were not done using the debug player and they were not running in debug mode which is very important in specific cases. Each test case was running ten times. The result shown is always the average execution time of the ten runs. This way two tests do not conflict with the garbage collection and each test is just responsible for its own memory usage. Before each run there is a ten seconds delay in order to not conflict with the Flash player starting procedure.

From result we see that initializing objects and arrays with new constructor is slower then directly with {} and []. So it may be useful to keep in mind that when you creating objects or arrays use:
var array:Array = [];
var obj:Object = {};

instead of
var array:Array = new Array();
var obj:Object = new Object();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package {
   
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    import flash.utils.setTimeout;
    import flash.system.Capabilities;
   
    [SWF(frameRate = '255')]
   
    public class TestCase extends Sprite {
        private static const n: int = 100000;
       
       
        public function TestCase() {
            setTimeout(runTest, 10000);
        }
       
        private function runTest(): void {
            var a: Number = 0;
            for ( var i: int = 0; i < 10; ++i ) a += test03();
            a /= 10;
            showResults(a);
        }
       
        private function showResults(result_:Number):void {
            var result_txt:TextField = new TextField();
            result_txt.x = result_txt.y = 10;
            result_txt.width = 300;
            result_txt.text = "Iterations: [10^" + (String(n).length - 1) + "], int[ms]: " + result_ +"\nisDebugger: " + Capabilities.isDebugger + "\nversion: " + Capabilities.version;
            addChild(result_txt);
        }
       
       
        // 1. Iterations: [10^5], int[ms]: 28.6
        // 2. Iterations: [10^5], int[ms]: 28.7
        private function test00(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:int = 0; i < n; ++i ) {
                var obj:Object = new Object();
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^5], int[ms]: 22.1
        // 2. Iterations: [10^5], int[ms]: 22.1
        // 3. Iterations: [10^5], int[ms]: 22.6
        private function test01(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:int = 0; i < n; ++i ) {
                var obj:Object = { };
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^5], int[ms]: 58.8
        // 2. Iterations: [10^5], int[ms]: 58.8
        private function test02(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:int = 0; i < n; ++i ) {
                var array:Array = new Array();
            }
           
            //test end
            return (getTimer() - startTime);
        }
       
        // 1. Iterations: [10^5], int[ms]: 23.7
        // 2. Iterations: [10^5], int[ms]: 24
        // 3. Iterations: [10^5], int[ms]: 23.6
        private function test03(): int {
            var startTime:int = getTimer();
           
            //test start
            for (var i:int = 0; i < n; ++i ) {
                var obj:Array = [];
            }
           
            //test end
            return (getTimer() - startTime);
        }
    }
}