その他の最適化

TextField オブジェクトに対しては、+= 演算子の代わりに appendText() メソッドを使用します。

TextField クラスの text プロパティを操作する場合は、+= 演算子の代わりに appendText() メソッドを使用します。appendText() メソッドを使用すると、パフォーマンスが向上します。

例えば、次のコードでは += 演算子を使用しており、ループ処理の実行時間は 1,120 ミリ秒です。

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 

次の例では、+= 演算子を 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 

これで、このコードの実行時間は 847 ミリ秒になります。

可能な場合は、ループの外でテキストフィールドを更新してください。

このコードは、簡単なテクニックを利用してさらに最適化することができます。各ループの内部でテキストフィールドを更新すると、ループ内処理が増加します。ストリングを結合し、ループの外でストリングにテキストフィールドに割り当てるだけで、コードの実行時間が大幅に短縮されます。これで、コードの実行時間は 2 ミリ秒になります。

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 

HTML テキストを操作する場合は、前者の方法では処理に時間がかかり、場合によっては Flash Player で Timeout 例外がスローされます。例えば、基になるハードウェアが非常に低速の場合、例外がスローされます。

注意: Adobe® AIR® では、この例外はスローされません。
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 ); 

ループの外でストリングに値を代入することにより、コードの実行時間はわずか 29 ミリ秒に短縮されます。

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 
注意: Flash Player 10.1 および AIR 2.5 では、String クラスが改善され、ストリングのメモリ使用量が低減しています。
可能な場合は、角括弧演算子の使用を避けてください。

角括弧演算子を使用すると、パフォーマンスが低下する可能性があります。参照をローカル変数に格納することにより、この演算子の使用を回避できます。次のコード例は、角括弧演算子の非効率な使用を示しています。

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 

次のように最適化して、角括弧演算子の使用回数を減らすことができます。

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 
可能な場合はコードをインライン化して、コード内の関数呼び出しの回数を減らしてください。

関数呼び出しは負荷を増加させる可能があります。コードをインライン化して、関数呼び出しの回数を削減するようにします。コードのインライン化は、純粋なパフォーマンスの最適化に適した方法です。ただし、インラインコードではコードの再利用が困難で、SWF ファイルのサイズが大きくなる可能性があるので注意してください。一部の関数呼び出し(Math クラスのメソッドなど)は、簡単にインライン化できます。次のコードでは、Math.abs() メソッドを使用して絶対値を計算します。

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

Math.abs() による計算は、手動で記述して、インライン化することができます。

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

関数呼び出しをインライン化すると、コードは 4 倍以上も高速化されます。この方法は、様々な状況で役立ちます。ただし、コードの再利用や管理容易性に与える影響について注意する必要があります。

注意: コードサイズにより、プレーヤーの全体的な実行に大きな影響があります。アプリケーションに大量の ActionScript コードが含まれている場合、仮想マシンはコードの検証と JIT コンパイルに相当の時間を費やします。プロパティ参照が遅くなる可能性があります。これは、継承階層が深くなるのと、内部キャッシュのスラッシュが大きくなる傾向があるためです。コードサイズを減らすには、Adobe® Flex® フレームワーク、TLF フレームワークライブラリまたはサードパーティ製 ActionScript ライブラリの使用を避けてください。
ループでステートメントを評価することは避けます。

ループ内でステートメントを評価しないようにして、最適化を図ることもできます。次のコードは、配列に対して反復処理を行います。反復処理ごとに配列の長さを評価するので、コードは最適化されていません。

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

値を保存して再利用する方が確実です。

var lng:int = myArray.length; 
 
for (var i:int = 0; i< lng; i++) 
{ 
}
while ループには反転を使用します。

反転の while ループは前進ループよりも高速です。

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

これらのヒントは、ActionScript を最適化するいくつかの方法を示しており、1 行のコードによってパフォーマンスとメモリに大きな影響があることがわかります。その他にも、ActionScript を最適化する多くの方法があります。詳しくは、http://www.rozengain.com/blog/2007/05/01/some-actionscript-30-optimizations/ を参照してください。