Różne inne sposoby optymalizacji

Dla obiektu TextField należy stosować metodę appendText() zamiast operatora += .

Przy pracy z właściwością text klasy TextField należy korzystać z metody appendText() zamiast z operatora += . Metoda appendText() zapewnia większą wydajność.

Przykład: w poniższym kodzie wykorzystano operator += , a wykonanie całej pętli trwa 1120 ms:

addChild ( myTextField ); 
  
myTextField.autoSize = TextFieldAutoSize.LEFT; 
var started:Number = getTimer(); 
  
for (var i:int = 0; i< 1500; i++ ) 
{ 
    myTextField.text += "ActionScript 3"; 
} 
  
trace( getTimer() - started ); 
// output : 1120 

W poniższym przykładzie operator += został zastąpiony metodą appendText() :

var myTextField:TextField = new TextField(); 
addChild ( myTextField ); 
myTextField.autoSize = TextFieldAutoSize.LEFT; 
  
var started:Number = getTimer(); 
  
for (var i:int = 0; i< 1500; i++ ) 
{ 
    myTextField.appendText ( "ActionScript 3" ); 
} 
 
trace( getTimer() - started ); 
// output : 847 

Wykonanie kodu teraz trwa 847 ms.

W miarę możliwości aktualizacje pól tekstowych należy przeprowadzać poza pętlami.

Poniższy kod można dodatkowo zoptymalizować, stosując prostą technikę. Aktualizacja pola tekstowego w każdej pętli powoduje znaczne wykorzystanie zasobów procesora. Prosta konkatenacja ciągu znaków i przypisanie do niego pola tekstowego poza pętlą znacznie skraca czas wykonywania kodu. Wykonywanie poniższego kodu trwa 2 ms:

var myTextField:TextField = new TextField(); 
addChild ( myTextField ); 
myTextField.autoSize = TextFieldAutoSize.LEFT; 
 
var started:Number = getTimer(); 
var content:String = myTextField.text; 
  
for (var i:int = 0; i< 1500; i++ ) 
{ 
    content += "ActionScript 3"; 
} 
  
myTextField.text = content; 
  
trace( getTimer() - started ); 
// output : 2 

W przypadku pracy z tekstem HTML poprzedni kod jest wykonywany tak wolno, że w niektórych przypadkach zwraca wyjątek Timeout w programie Flash Player. Na przykład: wyjątek może zostać zgłoszony, jeśli sprzęt bazowy działa zbyt wolno.

Uwaga: Adobe® AIR® nie zgłasza tego wyjątku.
var myTextField:TextField = new TextField(); 
addChild ( myTextField ); 
myTextField.autoSize = TextFieldAutoSize.LEFT; 
  
var started:Number = getTimer(); 
  
for (var i:int = 0; i< 1500; i++ ) 
{ 
    myTextField.htmlText += "ActionScript <b>2</b>"; 
} 
 
trace( getTimer() - started ); 

Przypisanie wartości do ciągu znaków poza pętlą powoduje, że kod jest wykonywany w zaledwie 29 ms:

var myTextField:TextField = new TextField(); 
addChild ( myTextField ); 
myTextField.autoSize = TextFieldAutoSize.LEFT; 
  
var started:Number = getTimer(); 
var content:String = myTextField.htmlText; 
  
for (var i:int = 0; i< 1500; i++ ) 
{ 
    content += "<b>ActionScript<b> 3"; 
} 
  
myTextField.htmlText = content; 
  
trace ( getTimer() - started ); 
// output : 29 
Uwaga: W programie Flash Player 10.1 i środowisku AIR 2.5 klasa String została udoskonalona, dzięki czemu ciągi znaków zajmują mniej miejsca w pamięci.
Jeśli nie jest to konieczne, nie należy stosować operatora nawiasu kwadratowego.

Użycie operatora nawiasu kwadratowego może spowodować spowolnienie wykonywania kodu. Aby uniknąć konieczności użycia tego operatora, można zapisać odwołanie w zmiennej lokalnej. W poniższym przykładzie kodu przedstawiono niewydajne zastosowanie operatora nawiasu kwadratowego:

var lng:int = 5000; 
var arraySprite:Vector.<Sprite> = new Vector.<Sprite>(lng, true); 
var i:int; 
  
for ( i = 0; i< lng; i++ ) 
{ 
    arraySprite[i] = new Sprite(); 
} 
  
var started:Number = getTimer(); 
  
for ( i = 0; i< lng; i++ ) 
{ 
    arraySprite[i].x = Math.random()*stage.stageWidth; 
    arraySprite[i].y = Math.random()*stage.stageHeight; 
    arraySprite[i].alpha = Math.random(); 
    arraySprite[i].rotation = Math.random()*360; 
} 
  
trace( getTimer() - started ); 
// output : 16 

W poniższej zoptymalizowanej wersji ograniczono użycie tego operatora:

var lng:int = 5000; 
var arraySprite:Vector.<Sprite> = new Vector.<Sprite>(lng, true); 
var i:int; 
  
for ( i = 0; i< lng; i++ ) 
{ 
    arraySprite[i] = new Sprite(); 
} 
  
var started:Number = getTimer(); 
var currentSprite:Sprite; 
  
for ( i = 0; i< lng; i++ ) 
{ 
    currentSprite = arraySprite[i]; 
     currentSprite.x = Math.random()*stage.stageWidth; 
     currentSprite.y = Math.random()*stage.stageHeight; 
     currentSprite.alpha = Math.random(); 
     currentSprite.rotation = Math.random()*360; 
} 
  
trace( getTimer() - started ); 
// output : 9 
W miarę możliwości należy stosować kod wstawiany bezpośrednio, aby ograniczyć liczbą wywoływań funkcji w kodzie.

Wywoływanie funkcji może być kosztowne. Aby zmniejszyć liczbę wywołań funkcji, należy stosować kod wpisywany bezpośrednio. Stosowanie kodu bezpośredniego jest dobrą metodą optymalizacji wydajności. Należy jednak pamiętać o tym, że ponowne wykorzystanie kodu bezpośredniego może być trudniejsze, zaś ta technika programowania może powodować zwiększenie objętości pliku SWF. Niektóre wywołania funkcji, np. metod klasy Math, mogą być łatwo przenoszone bezpośrednio do kodu. Poniższy kod wykorzystuje metodę Math.abs() do obliczania wartości bezwzględnych:

const MAX_NUM:int = 500000; 
var arrayValues:Vector.<Number>=new Vector.<Number>(MAX_NUM,true); 
var i:int; 
  
for (i = 0; i< MAX_NUM; i++) 
{ 
    arrayValues[i] = Math.random()-Math.random(); 
} 
  
var started:Number = getTimer(); 
var currentValue:Number; 
  
for (i = 0; i< MAX_NUM; i++) 
{ 
    currentValue = arrayValues[i]; 
    arrayValues[i] = Math.abs ( currentValue ); 
} 
  
trace( getTimer() - started ); 
// output : 70

Obliczenie realizowane przez metodę Math.abs() można łatwo zrealizować ręcznie i przenieść bezpośrednio do kodu:

const MAX_NUM:int = 500000; 
var arrayValues:Vector.<Number>=new Vector.<Number>(MAX_NUM,true); 
var i:int; 
  
for (i = 0; i< MAX_NUM; i++) 
{ 
    arrayValues[i] = Math.random()-Math.random(); 
} 
  
var started:Number = getTimer(); 
var currentValue:Number; 
  
for (i = 0; i< MAX_NUM; i++) 
{ 
    currentValue = arrayValues[i]; 
    arrayValues[i] = currentValue > 0 ? currentValue : -currentValue; 
} 
  
trace( getTimer() - started ); 
// output : 15

Przeniesienie wywołania funkcji bezpośrednio do kodu powoduje ponadczterokrotny wzrost wydajności. Takie rozwiązanie jest użyteczne w wielu sytuacjach, ale należy pamiętać o wpływie, jaki może ono mieć na ewentualne ponowne wykorzystanie kodu i łatwości jego modyfikacji.

Uwaga: Ilość kodu w znacznym stopniu wpływa na ogólne działanie odtwarzacza. Jeśli aplikacja zawiera znaczne ilości kodu ActionScript, wówczas maszyna wirtualna przeznacza znaczną ilość czasu na sprawdzanie poprawności kodu i kompilowanie JIT. Wyszukiwanie właściwości może być spowolnione z powodu głębszych hierarchii dziedziczenia i ponieważ wewnętrzne pamięci podręczne wykazują tendencję do częstszych awarii. Aby ograniczyć ilość kodu, należy unikać korzystania ze struktury Adobe® Flex®, biblioteki struktury TLF oraz wszelkich dużych bibliotek ActionScript innych firm.
Należy również unikać określania wartości instrukcji w pętlach.

Innym sposobem optymalizacji może być rezygnacja z wyznaczania wartości instrukcji w każdej pętli. Poniższy kod wykonuje iteracje na tablicy, ale nie jest zoptymalizowany, ponieważ długość tablicy jest obliczana w każdej iteracji:

for (var i:int = 0; i< myArray.length; i++) 
{ 
}

Lepszym rozwiązaniem jest zapisanie wartości i jej ponowne wykorzystanie:

var lng:int = myArray.length; 
 
for (var i:int = 0; i< lng; i++) 
{ 
}
Dla pętli while należy stosować kolejność odwrotną.

Pętla while wykonana w kolejności odwrotnej działa szybciej niż pętla wykonana do przodu:

var i:int = myArray.length; 
 
while (--i > -1) 
{ 
}

Przedstawiono wskazówki optymalizacji kodu ActionScript oraz wyjaśniono, w jaki sposób jeden wiersz kodu może wpłynąć na wydajność i wykorzystanie pamięci. Istnieje również wiele innych metod optymalizacji kodu ActionScript. Aby uzyskać więcej informacji, należy skorzystać z następującego łącza: http://www.rozengain.com/blog/2007/05/01/some-actionscript-30-optimizations/ .