26
mei 10

Actionscript 3.0 performance tips

Het leek me handig om een artikel te plaatsen met wat kleine performance tips.
Je performance in de gaten houden is een belangrijk onderdeel bij het maken van goede applicaties.
Bij de gemiddelde fotogallery of portfolio site is dit misschien niet zo’n big deal. Maar wanneer je met particles of games aan de slag gaat en je bepaalde code uitvoert in onEnterFrame handlers en veel door loops loopt, is het zeker de moeite waard om zo efficiënt mogelijk te programmeren.
Vaak zijn het kleine handigheidjes die je jezelf even aan moet wennen.

Als iemand toevoegingen heeft of onjuistheden opmerkt. Dan hoor ik het graag.

Math.max en Math.min zijn traag

Het gebruik van Math.max en Math.min is erg traag in vergelijking met een if statement.

1
2
3
4
5
6
7
8
9
10
11
//In plaats van

var v1:Number = 10;
var v2:Number = 20;
var v3:Number = Math.max(v1,v2);

//prefereer ik (± 8.5x zo snel)

var v1:Number = 10;
var v2:Number = 20;
var v3:Number = (v1 >= v2) ? v1 : v2;

Math.abs is traag.

Het gebruik van Math.abs is erg traag in vergelijking met een if statement.

1
2
3
4
5
6
7
8
9
//In plaats van

var v1:Number = -10;
var v2:Number = Math.abs(v1);

//prefereer ik (± 7.5x zo snel)

var v1:Number = -10;
var v2:Number = (v1 < 0) ? -v1 : v1;

Math.floor is trager dan casten naar int.

Je kunt Math.floor eenvoudig vermijden door te casten naar int.

1
2
3
4
5
6
7
8
var v1:Number = 10.5;
var v2:int;

//In plaats van
v2 = Math.floor(v1);

//prefereer ik (± 3.5x zo snel)
v2 = int(v1);

Er is nog een snellere methode. Deze is wat minder leesbaar, maar 1.5x sneller dan de int(value) methode.

1
2
3
4
var v1:Number = 10.5;
var v2:int;

v2 = v1>>0;

Bovenstaande methodes werken alleen bij positieve getallen!
Als het getal ook negatief kan zijn moet je hier een check voor maken.
Dit is iets trager, maar nog steeds veel sneller dan Math.floor.

1
v2 = (v1>0) ? v1 >>0 : (v1>>0)-1;

Math.ceil is ook trager dan casten naar int.

Voor Math.ceil geldt eigenlijk hetzelfde als voor Math.floor.
Alleen kun je niet zomaar naar int casten en er 1 bij optellen:

Math.ceil(1.2) == 2;
int(1.2)+1 == 2;
Math.ceil(1) == 1;
int(1)+1 == 2;

Daarom gebruiken we een inline if statement.

1
2
3
4
5
6
7
8
var v1:Number = 10.5;
var v2:int;

//In plaats van
v2 = Math.ceil(v1);

//prefereer ik (± 2.5x zo snel)
v2 = (int(v1) == v1) ? v1 : int(v1) + 1;

En de bitwise methode zoals bij Math.floor geeft hier zelfs nog iets meer winst dan bij Math.floor het geval is.

1
2
3
4
var v1:Number = 10.5;
var v2:int;

v2 = (v1 >> 0 == v1) ? v1 : (v1 >> 0) + 1;

Bovenstaande methodes werken alleen bij positieve getallen!
Als het getal ook negatief kan zijn moet je hier een check voor maken.
Dit is iets trager, maar nog steeds veel sneller dan Math.ceil.

1
v2 = (v1 >> 0 == v1) ? v1 : (v1 < 0) ? (v1 >> 0) : (v1 >> 0) + 1;

Vermenigvuldigen is sneller dan delen.

1
20 / 2 is ± 7% langzamer dan 20 * .5;

Bitwise operations zijn super snel!

Het gebruik van bitwise operations kan je project een flinke performanceboost geven.
Deze zijn echt super snel mits ze gebruikt worden in combinatie met integers.
Als je Numbers gebruikt kun je zomaar voor verrassingen komen te staan.

1
2
3
4
5
6
var v1:Number = 20;
var v2:Number;

v2 = v1 * .5;
//is ± 1.4x zo snel als
v2 = v1 >> 1;

Maar als we integers gebruiken:

1
2
3
4
5
6
var v1:int = 20;
var v2: int;

v2 = v1 >> 1;
//is ± 1.6x zo snel als
v2 = v1 * .5;

Bitwise operations ronden je getallen wel af op hele getallen. Maar dat zie ik vaker als een voordeel dan een nadeel.
Bijvoorbeeld bij het uitlijnen van textfields. Je wilt textfields altijd op hele pixels plaatsen.
Vaak wil je een textfield in het midden van een knop zetten. Ik gebruik daarvoor de volgende code:

1
_txt.x = width-_txt.width >> 1;

Een aantal bitwise tricks die in je voordeel kunnen werken mits je ze gebruikt met integers:

1
2
3
4
5
6
7
8
9
10
11
//delen door 2
value >> 1;

// Vermenigvuldigen met 2
value < < 1;

//positief/negatief omdraaien (± 1.2x zo snel)
~value + 1; // is gelijk aan: value * -1; //en is gelijk aan:  -value

//even/oneven controleren
(value & 1) == 0; //is gelijk aan: (value % 2) == 0;

Integers zijn sneller dan Numbers.

Sommige van de hierboven beschreven methode gaan uit van een bepaald datatype.
De behaalde resultaten kunnen namelijk nogal verschillen tussen bepaalde datatypen.

Voorbeeld:

1
2
3
4
5
6
var v1:int = -11;
var v2:int;
//dit:
v2 = v1*-1;
//is sneller dan
v2 = -v1;

Maar, als je ditzelfde met Numbers doet:

1
2
3
4
5
6
7
var v1:Number = -11;
var v2: Number;

//is dit ± 15% sneller:
v2 = -v1;
//dan:
v2 = v1*-1;

Over het algemeen zijn integers sneller.
Gebruik daarom ook altijd integers in loops en bij voorkeur uints als de loop optelt.
In flash player 9 was de performance van uints belachelijk slecht. In veel gevallen waren uints zelfs trager dan Numbers.
Hierom kozen veel developers voor ints als loop counter. Ik ben hier eigenlijk nooit in mee gegaan, omdat het meer sense maakt om uints te gebruiken in een positie loop. Daar zijn ze immers voor.
Gelukkig is de performance van uints in flash player 10 zoals deze moet zijn. (hetzelfde of zelfs iets sneller dan ints)

loop voorbeeld:

1
2
3
4
5
for(var i:uint = 0; i&lt;100; i++)
//ipv
for(var i:int = 0; i&lt;100; i++)
//en ipv
for(var i:Number = 0; i&lt;100; i++)

Als je loop counter negatief kan worden gebruik je natuurlijk ints.

Gebruik geen array.push als dit niet nodig is.

1
2
3
4
5
var arr:Array = [];
for(var a:uint = 0; a < 10000000; a++)
{
    arr[a] = a ;
}

is eens zo snel als:

1
2
3
4
5
var arr:Array = [];
for(var a:uint = 0; a < 10000000; a++)
{
    arr.push(a);
}

Gebruik Vectors waar je maar kunt.

1
2
3
4
5
6
var arr:Vector.<uint> = new Vector.<uint>();

for(var a:uint = 0; a < 10000000; a++)
{
    arr[a] = a ;
}

is eens zo snel als:

1
2
3
4
5
6
var arr:Array = [];

for(var a:uint = 0; a < 10000000; a++)
{
    arr[a] = a;
}

Sla de length van je array/vector op in een variable voor je gaat loopen.

1
2
3
4
5
var l:Number = arr.length;
for (var i:uint = 0; i < l; i++ )
{
    v2 = arr[i];
}

is 5x! sneller dan:

1
2
3
4
for (var i:uint = 0; i < arr.length; i++ )
{
    v2 = arr[i];
}

De ‘one dot’ regel.

Als je meerdere keren een property aan wilt spreken waar je meer dan één . voor nodig hebt, sla hem dan op in een lokale variable.

Voorbeeld:

1
2
3
4
5
6
7
8
9
10
11
var mc:MovieClip = new MovieClip();
mc.data = {};
mc.data.x = 10;

var value:Number;
var prop:Number = mc.data.x;

for(var a:uint = 0; a < 10000000; a++)
{
    value = prop;  
}

is 10x! zo snel als:

1
2
3
4
5
6
7
8
9
10
var mc:MovieClip = new MovieClip();
mc.data = {};
mc.data.x = 10;

var value:Number;

for(var a:uint = 0; a < 10000000; a++)
{
    value = mc.data.x;
}

Gebruik de ternary operator.

De ternary operator is niet zozeer sneller dan een ‘normaal’ if statement, maar het maakt je code wel een stuk compacter en leesbaarder. Let wel op dat je het condition gedeelte altijd tussen ( ) zet. Doe je dit niet werkt je code prima, geen error aan de lucht. Maar het is 10% langzamer dan wanneer het condintion gedeelte tussen ( ) staat.

Dus:

1
2
3
result = (value1==value2) ? x : y;
//ipv
result = value1==value2 ? x : y;
1
2
3
4
5
6
var v1:Number = -10;
var v2:Number;
//dit:
v2 = (v1 < 0) ? -v1 : v1;
// is iets langzamer dan:
(v1 < 0) ? v2 = -v1 : v2 = v1;

In het bovenstaande voorbeeld gebruik ik persoonlijk altijd de langzamere methode.
We praten hier over een paar milliseconden op 10000000 checks. En ik vind de eerste methode een stuk leesbaarder.

Nog een lijstje met tips:

* Gebruik een zo strikt mogelijk datatype.
* Enterframes zijn sneller dan timers.
* Gebruik zo min mogelijk enterframe handlers en/of timer handlers.
* Constanten zijn sneller dan variablen.
* Zet geen ‘zware’ code in je constructors. Maak liever een init functie die je aanroept in je constructor.
* Callbacks meegeven is sneller dan events dispatchen.
* Test zelf hoe bepaalde optimalisaties uitpakken in jouw project.
* Draaf niet te ver door met optimaliseren. Een paar milliseconden winst in ruil voor een moeilijk leesbare code zou ik niet aan willen raden.

Stellingen in bovenstaand document zijn gebaseerd op testresultaten behaald met de flash 10.1 IDE player van CS5 op Windows Vista 64bit.
Vooral in flash player 9 kunnen de resultaten nog wel eens anders uitpakken. Test daarom altijd zelf en neem niet zomaar aan wat je op internet leest.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

23
feb 10

Sorteren op datum, UTC string

Ik ben bezig een eenvoudige class te maken om Twitter tweets in een swf te tonen.
De bestaande API’s vind ik wat overkill voor hetgeen ik wil maken. Ik wil gewoon een xml met de laatste 20 tweets van een bepaalde user en verder niets.

Die xml kun je gewoon ophalen bij Twitter:
http://twitter.com/statuses/user_timeline/marcvanzon.xml

Omdat ik de mogelijkheid wil hebben om tweets van verschillende Twitter accounts  in één array te hebben staan, moet ik sorteren op het created_at veld om deze tweets in een juiste chronologische volgorde te zetten.

Twitter geeft in het created_at veld een zogenaamde UTC string met de datum en tijd mee.
Leuk en aardig, maar hoe ga je dat sorteren?
“Mon” komt namelijk altijd voor “Sat” als je dat gewoon met een array.sortOn functie aanpakt.

Uren gezocht op internet leverde geen eenvoudige oplossing op. Dus ben ik zelf wat gaan proberen.
Uiteindelijk was het veel eenvoudiger dan ik had durven hopen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr:Array = ["Tue Feb 23 00:11:49 +0000 2010", "Sat Jan 24 22:14:29 +0000 2009", "Wed Oct 28 19:41:35 +0000 2009", "Sun Feb 21 19:39:10 +0000 2010", "Sun Feb 21 19:39:11 +0000 2010"];
trace(arr);

//we maken een lege array.  Hierin maken we dalijk objecten met de datum in UTC string en in miliseconden.
var arr1:Array = new Array();
//we lopen door de array met datum
for (var a in arr) {
//hier maken we de objecten met UTC string en de tijd in miliseconden vanaf  January 1, 1970, UTC.
//uit de livedocs:
/*
* parse(date:String):Number
* [static] Converts a string representing a date into a number equaling the number of milliseconds elapsed since January 1, 1970, UTC.
*/

arr1.push( { date:arr[a], time:Date.parse(arr[a]) } );
}
//vervolgens sorteren we de nieuwe array op miliseconden. Het item met de hoogste waarde komt vooraan in de array te staan.
arr1.sortOn("time", Array.NUMERIC);
//we draaien de array om, we willen immers niet het oudste maar het recentste item vooraan hebben.
arr1.reverse();
//en we loopen nog een keer door de array om te kijken of het gelukt is.
for (var a in arr1) {
//we tracen het veld met de UTC string en concluderen dat het nog werkt ook :D
trace(arr1[a].date);
}
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

17
jan 10

Wordpress > ping.fm > facebook pages

Wederom een test om blog items automatisch op een facebook page te krijgen.
Helaas lijkt er geen plugin te bestaan om dit netjes, met image, tekst, links, etc voor elkaar te krijgen.
Ik neem inmiddels genoegen met alleen tekst.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

17
jan 10

SWFAddress

Ik was net bezig met de implementatie van SWFAddress voor een project.
Om één of andere rede wilde het maar niet werken.
Uiteindelijk kwam ik erachter dat swfAddress niet werkt als je de js file eerder include dan de js file van SWFObject.

Een korte blog post. Maar hopelijk een uitkomst voor mensen waarbij SWFAddress ook niet werkt en niet kunnen vinden waarom.

English:

I was working on the SWFAddress implementation for a project.
It just wouldn’t work for some reason.
Eventualy I found out that SWFAddress won’t work properly if you include the js file before you include the js file of SWFObject.

A small blogpost. But hopefully useful for people that encounter the same problem and can’t find the solution.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

08
dec 09

Fotografie

Canon 450DNa de aanschaf van een Wacom Bamboo heb ik de smaak van het foto-bewerken weer helemaal te pakken.
Vooral het bijwerken van portretten is een favoriete bezigheid van me geworden, puistje weg, rimpeltje glad strijken, etc.
Maar, ik deed dit altijd met foto’s die bij een vriend/kennis/familielid van een huis-tuin-en-keuken cameraatje  komen. Mede hierdoor kwam ik in de, ik wil een digitale-spiegel-reflex camera fase.

Na dagen informatie lezen, fora afstruinen en reviews vergelijken heb ik een Canon 450D met Sigma 18-200 OS lens gekocht.
Heerlijke machine om in je handen te hebben! Veel knopjes, daar ben ik dol op.

Dit alles speelde zich een paar dagen voor een impulsief geboekte reis met een goede vriend naar Gran Canaria af.
Er zat dus niets anders op dan binnen die dagen zoveel mogelijk knopjes proberen om de kans op het schieten van degelijke vakantiekiekjes wat te vergroten.
Ik moet bekennen dat ik met voor 80% beperkt heb tot de default standen van de camera. Jammer dat het schieten in RAW data in deze standen geen optie is..
Maar, beter een minder bewerkbare foto dan een totaal mislukte..

Nu ben ik inmiddels weer thuis en ben ik de gemaakte foto’s aan het selecteren. Van de 500+ foto’s is zeker 90% niet meer dan een ‘gewoon vakantiekiekje”.
Maar die paar foto’s die net dat beetje meer hebben, waar ik op het gemak een paar minuten naar ga zitten staren, die foto’s maken de kapitaal-verslindende impulsaankopen van tablet en camera een heel eind goed.

Tegen de tijd dat ik uitgeselecteerd ben ga ik de mooiste kiekjes ook zeker op deze blog plaatsen.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

30
okt 09

Social Networking

Nu ik me eenmaal heb begeven in de wereld van social networking wil ik het ook gelijk goed aanpakken. Helaas is dat makkelijker gezegd dan gedaan.

Ik ben al verschillende avonden bezig geweest om alles aan elkaar te koppelen. En ‘alles’ betekent in deze: Blog > Facebook business page > Twitter > Facebook profile.

Dat laatste stuk ging prima. Dus ik update de status op Facebook pagina, automatische tweet en die tweet komt weer op mijn Facebook profiel.

Maar toen moest Wordpress ervoor.. Eerst geprobeerd met een Facebook plugin genaamd ‘RSS Social’. M’n blog kwam inderdaad op mijn Facebook Page, maar niet als status update. Dus geen tweet en geen profiel update…

Nu heb ik een plugin gevonden voor wordpress, ‘Status Updater’. Hopelijk bereik ik daarmee wel het gewenste resultaat. Even afwachten.

Lang verhaal kort: Heel deze post is eigenlijk niet meer dan een veredeld test berichtje.

Update:

Helaas, Status Updater geeft ook problemen. Nieuwe poging, Wordpress 2 Ping.fm  plugin…

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

30
okt 09

Snake!

snake

Screenshot van snake game

Het is inmiddels al weer een aantal jaar geleden dat ik dit spelletje gemaakt heb. Ik wilde me verdiepen in actionscript 3.0 en dit leek me een prima manier om er een beetje in te komen.

Tegenwoordig springen de tranen me in de ogen als me gevraagd wordt een project in actionscript 2.0 te schrijven. Opmerkelijk, hoe je eerst opziet tegen een verandering en uiteindelijk niet meer terug wilt.

Maar even terug naar het spelletje. Er komen nog steeds highscores bij, snake is nog steeds een populair spelletje en ik heb een blog te vullen. Dus, vandaar dat ik hem hier nog eens onder de aandacht breng.

Op t plaatje klikken! ;)

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm

29
okt 09

Hallo wereld!

Daar is ie dan. Eindelijk een blog.

Ik heb jaren geprobeerd het bestaan social networks en dergelijke  te ontkennen, maar t wordt nu toch wel tijd om er aan mee te gaan doen.

Ik hoop deze blog te vullen met informatie die niet alleen voor mij, maar ook voor andere interessant is. Dit zal voornamelijk neerkomen op items betreffende het internet, flash, actionscript etc.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogplay
  • Hyves
  • Live
  • MySpace
  • Twitter
  • LinkedIn
  • NuJIJ
  • Ping.fm
Get Adobe Flash playerPlugin by wpburn.com wordpress themes