views:

491

answers:

5

Things like the code below is super slow:

var str:String = ""
for (var i:Number = 0 ; i<1000000000000000000 ; ++i) {
    str += "someLongLongLongLongLongLongLongLongLongString";
}

There is StringBuilder in Java but seems there is no equivalent for AS. So, how do you guys handle large strings concatenation?


Update:

Thanks for everyone's answer!

I've just coded my own testing program. Using += is already the fastest... What is slow is whan put it on a TextArea...

I've up voted for most of you as the advices make sense :) although my test result show that seems my question is somewhat problematic since I ask for something better then what is already the best :P

+4  A: 

I can't say I'm experienced with ActionScript, but for ECMAScript in general, I've found that arrays can help speed up string concatenation (JavaScript example follows):

var sb = [];
for (var i = 0; i < 10000000000; i++) {
    sb.push('longlonglong');
    // In this particular case you can avoid a method call by doing:
    //sb[i] = 'longlonglong';
}
var str = sb.join('');
Blixt
+1, since this is true for most JS interpretors (even though it seems that `sb[i] = 'longlonglong'` is even faster ... for AVM2, this trick doesn't work, neither with push, nor with array access ...
back2dos
whoop, sorry for the redundancy, didn't quite read the comment line ... :)
back2dos
I've just found that even JS, `+=` is the fastest! See my question update!
Andy Li
+6  A: 

Yes, that would be slow, even with a StringBuilder. My question is: why are you trying to create a string 46 exabytes in size?

At some point, a more conventional external-storage (i.e., on-disk) method becomes a good idea but you seem to have passed even that point (based on the disk arrays in common use today).

I don't generally have this problem since I tend not to use strings for storing such huge things. String are generally meant for somewhat smaller objects. What you have there is a sizable data warehouse, not a name or address field :-)

paxdiablo
I know what you mean. But sometime we don't have choice since the UI components use String...
Andy Li
+2  A: 

Two things generally make operations like these slow:

  • The string grows out of the memory allocated for it, so it has to be re-allocated. This involves the heap memory manager, and copying the contents. As the contents grows, this means it is copied around a lot, and that the memory system has to work pretty hard.
  • If the string is not stored in a way that means its length is available as a O(1) operation, concatenation first has to step through the entire string to find the length, i.e. where to start concatenating. The means each single concatenation takes time proportional to the length of the target string.

I'm sure at least one of these is hitting you (the latter might not, not sure how strings are represented internally in ActionScript).

unwind
+1 for the first ... the second is not the case for AVM2 (nor for AVM1) ...
back2dos
+3  A: 
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
performancetests.Strings (1 iterations)                                 
Player version: MAC 10,0,32,18 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
stringsWithConcatMethod                                   17555 17555.00
stringsWithPlusConcat                                      4972  4972.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

I'm not a masochist so I just used a 10000000 iteration loop on this:

var str:String = ""
for (var i:Number = 0 ; i<10000000 ; ++i) {
    str += "someLongLongLongLongLongLongLongLongLongString";
}

versus:

var str:String = ""
for (var i:Number = 0 ; i<10000000 ; ++i) {
    str = str.concat("someLongLongLongLongLongLongLongLongLongString");
}

Using Grant Skinner's AS3 Performance Test Harness. The String::concat method is even slower, though given your conditions as3 is likely to just be sloooow. (1 iteration in the result is 1 time going through the 10000000 iteration loops). I was fairly surprised by the result. I thought concat would be faster.

Joel Hooks
Thanks for the test (+1 for that:) )! You make me write my own test program too! See my question update :)
Andy Li
-1, extending the string on every iteration - no matter the method - is O(n^2) and is the wrong way to go.
orip
+2  A: 

you are conducting type abuse here ... :D ... on AVM2, strings are meant for text representation ... they are always unicode, which is why they need more than 2 bytes per char ... so they are not suitable for storing a i-will-make-your-heap-explode sized ascii sequence ... if you really want to manipulate a sh*tload of data, then go for flash.utils::ByteArray ... not that it is particularly faster, but it is semantically more correct and has a lower memory footprint ... plus it has native compression methods, which is what i'd highly recomend in your case ... :P

back2dos
Thanks for the advice! That's what I thought originally. But I found String's `+=` is the fastest :PSince I want to display the text, a String need to be created in any case...
Andy Li