« Adobe MAX 2007 | Main | We need help testing web services! »

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?

TextField is a Flash Player class and I believe appendText() relies on some other native code via replaceText().

Is fromCharCode faster than just

result = buffer.join("");

?

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.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)