Avoiding String Concatenation
When writing a String based encoder in ActionScript you quickly find yourself needing to build up the encoded String a character or so at a time. Without a StringBuffer type in ActionScript you may be tempted to use String concatenation as a simple method to build up a String. The problem with this approach is a number of temporary Strings are created as a result and will hang around until garbage collection catches up.
for (var i:uint =0; i < source.length(); i++)
{
result += encodeSomething(source.getCharAt(i));
}
To avoid large memory spikes, a better approach is to build up an Array of character code points as integers and then using them to construct a String in one step using the String.fromCharCode() function:
var buffer:Array = [];
for (var i:uint =0; i < source.length(); i++)
{
buffer.push(encodeSomethingAsInt(source.getCharAt(i)));
}
result = String.fromCharCode.apply(null, buffer);
Since fromCharCode takes a variable number of arguments, we use Function.apply to pass the Array of integers in a single call.
Note that the arguments of Function.apply end up on the stack, so to avoid a stack overflow you should limit the size of the array to around 64,000 entries. You can always concatenate successive buffers into a final String.
Comments
Is this how the TextField class "appendText()" method works?
Posted by: Keith | October 14, 2007 9:47 PM
TextField is a Flash Player class and I believe appendText() relies on some other native code via replaceText().
Posted by: Peter Farland | October 15, 2007 11:37 PM
Is fromCharCode faster than just
result = buffer.join("");
?
Posted by: Joe | July 15, 2008 6:25 AM
I ran a quick test and it seems that String.fromCharCode() was around twice as fast as Array.join("") for a creating a String from a 100,000 char Array and over twice as fast for a 1,000,000 char Array.
The original purpose of fromCharCode() was to avoid temporary string creation from concatenation to keep memory and gc time down.
I was concerned to see that Strings created with Array.join() reported their length as a non-constant amount, where as String.fromCharCode always was repeatable and accurate.
Posted by: Peter Farland | July 15, 2008 10:57 PM