Para un objeto TextField, use el método
appendText()
en lugar del operador
+=
.
Al trabajar con la propiedad
text
de la clase TextField, utilice el método
appendText()
en lugar del operador
+=
. Al usar el método
appendText()
, se obtienen mejoras de rendimiento.
Por ejemplo, el siguiente código utiliza el operador
+=
y el bucle tarda 1120 ms en completarse:
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
En el siguiente ejemplo, el operador
+=
se reemplaza con el método
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
El código tarda ahora 847 ms en completarse.
Actualice los campos de texto fuera de los bucles, si es posible.
Este código se puede optimizar aún más utilizando una sencilla técnica. En la actualización del campo de texto en cada bucle se emplea mucho procesamiento interno. Simplemente al concatenar una cadena y asignarle el valor del campo de texto fuera del bucle, el tiempo de ejecución del código disminuye sustancialmente. El código tarda ahora 2 ms en completarse:
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
Al trabajar con texto HTML, el enfoque anterior resulta tan lento que se genera una excepción
Timeout
en Flash Player, en algunos casos. Por ejemplo, se puede emitir una excepción si el hardware subyacente es demasiado lento.
Nota:
Adobe® AIR® no emite esta excepción.
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 );
Al asignar el valor a una cadena fuera del bucle, el código necesita únicamente 29 ms para completarse:
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
Nota:
en Flash Player 10.1 y AIR 2.5, la clase String se ha mejorado, por lo que las cadenas utilizan menos memoria.
Si es posible, se debe evitar el uso del operador de corchetes.
La utilización del operador de corchetes puede ralentizar el rendimiento. Para evitar su uso, se puede almacenar la referencia en una variable local. En el siguiente código se muestra el uso ineficaz del operador de corchetes:
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
En la siguiente versión optimizada se reduce el uso del operador de corchetes:
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
Cuando sea posible, sitúe código entre líneas para reducir el número de llamadas a funciones.
Las llamadas a funciones pueden resultar caras. Intente reducir el número de llamadas a funciones moviendo el código en línea. El movimiento del código en línea constituye un buen modo de optimizar para un rendimiento total. Sin embargo, se debe tener en cuenta que el código en línea puede hacer que el código sea más difícil de reutilizar y puede aumentar el tamaño del archivo SWF. Algunas llamadas a funciones como, por ejemplo, los métodos de la clase Math, son más fáciles de mover en línea. En el siguiente código se utiliza el método
Math.abs()
para calcular valores absolutos:
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
El cálculo realizado por
Math.abs()
se puede llevar a cabo de forma manual y se puede mover en línea:
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
El movimiento de las llamadas a funciones en línea implica que la velocidad del código se multiplique por un valor superior a cuatro. Este enfoque resulta útil en diversas situaciones, pero se debe tener en cuenta el efecto que tiene en la reutilización y el mantenimiento.
Nota:
el tamaño del código tiene un gran impacto en la ejecución general del reproductor. Si la aplicación incluye grandes cantidades de código ActionScript, el equipo virtual emplea importantes cantidades de tiempo en la verificación del código y la compilación JIT. Las búsquedas de propiedades pueden resultar más lentas, debido a las jerarquías de herencia más profundas y a que las cachés internas tienden a una mayor hiperpaginación. Para reducir el tamaño del código, evite la utilización de la arquitectura Adobe® Flex®, la biblioteca de la arquitectura TLF o cualquier otra gran biblioteca de ActionScript de terceros.
Evite la evaluación de sentencias en bucles.
Se puede lograr otra optimización al no evaluar una sentencia dentro de un bucle. El siguiente código establece una iteración en un conjunto, pero no se optimiza porque la longitud del conjunto se evalúa en cada repetición:
for (var i:int = 0; i< myArray.length; i++)
{
}
Es mejor almacenar el valor y volver a utilizarlo:
var lng:int = myArray.length;
for (var i:int = 0; i< lng; i++)
{
}
Utilice el orden inverso para los bucles while.
Un bucle while en orden inverso es más rápido que un bucle forward:
var i:int = myArray.length;
while (--i > -1)
{
}
Estas sugerencias proporcionan algunas maneras de optimizar ActionScript, mostrando el modo en que una sola línea de código puede afectar al rendimiento y la memoria. Son posibles otras muchas optimizaciones de ActionScript. Para obtener más información, consulte el siguiente vínculo:
http://www.rozengain.com/blog/2007/05/01/some-actionscript-30-optimizations/
(en inglés).