Optimization / Speed tip for larger arrays

Monkey Targets Forums/Android/Optimization / Speed tip for larger arrays

Wylaryzel(Posted 2013) [#1]
Hiho,

I'm currently in process to develop my next game. The programming in monkey went very well and during the testing in HTML5/GWFL target I didn't care to much on speed. Nevertheless, the main target is aimed for mobile, especially android.

Yesterday I made some stress tests for the dungeon generation engine and was a bit astonished by the results I obtained (it generates a map sized 90x70 fields randomly). Such a generation takes around 6 seconds but on android it takes around 16 secs.

I made some further checks and today I made a simple for - next loop to test how long it would may take at least to convert the data into a long string (like to be stored with SaveState).

to check the performance I used:
local str:string = ""
for local i:int = 0 to 6300
   str += ",1"
next


with the above code and according to Dalvik debug monitor it takes around 16secs and the GC activities are incredibly?

Next I tried a similar function, but this time I used a string[] and after the for/next loop I joined the str. This took maximum 0.011 secs:
local strArray:string[6300]
for local i:int = 0 until 6300
    strArray[i] = "1"
next
local str:string = ","
str = str.Join(strArray)


This brings me to my question: as I have to store the state of around 20 dungeons with several additional information, I will have several conversation operations (from int to string for saving and back to int for loading).

How to you experts perform that action to write/read the SaveState? And has somebody an technical explanation for a newcomer why the first operation takes so long and invokes the GC like crazy?

Thx in advance


AdamRedwoods(Posted 2013) [#2]
strings are immutable in Monkey, so string operations always return a new one.

that said, monkey translates the
str+=",1"

to
t_str=t_str+",1";

in java.

so the problem is in java, a common problem, which is explained in stack overflow:
http://stackoverflow.com/questions/1532461/stringbuilder-vs-string-concatenation-in-tostring-in-java/1532547#1532547

so for performance reasons, in this case, i would use arrays.


Wylaryzel(Posted 2013) [#3]
Thanks for the information and especially the link :-) There are so many information in Goggle ( :-) ) that it's sometimes hard to identify the currect one :)

So its maybe best to build a string[] and convert it via a string.Join to and resolve it afterwards via a split-string. Looks complicated but knowing this now, I can work with corresponding functions :-)


Raph(Posted 2013) [#4]
Aha, I just sped up a text routine by 500% by moving much of it to arrays, and now I think I will move as much as I can!


muddy_shoes(Posted 2013) [#5]
If you want to do this and avoid manually handling the arrays there are a few StringBuilder implementations out there. I think Diddy has one and there's one tucked away in my json lib at the top of this file: https://code.google.com/p/monkey-json/source/browse/jsondata.monkey


Nobuyuki(Posted 2013) [#6]
yes, string immutability means that appending strings a lot and performing operations like this on android means they will be very slow. One way to deal with it, depending on the data, is to convert it to a char array and then to something like an IntStack to perform operations on it there, then return it all back. Java provides an object called StringBuilder to deal with this stuff natively; you can also mess with this if you are OK with working with native routines. Finally, diddy provides a stringbuilder class which supposedly is fast on Android. Consider using some of its methods to concat and append strings....