I have a method in engine i'm using (andengine) :
public final void setText(String pString){...}
my app is updating score every 1s from static int
mScoreText.setText(""+PlayerSystem.mScore);
The problem is that this way every second a new String object is created , and after 1 minute i have 59 String objects to collect by GC and additional AbstractStringBuilders and init 's...
I've found a partial solution on andengine forums like this :
private static StringBuilder mScoreValue = new StringBuilder("000000");
private static final char[] DIGITS = {'0','1','2','3','4','5','6','7','8','9'};
mScoreValue.setCharAt(0, DIGITS[(PlayerSystem.mScore% 1000000) / 100000]);
mScoreValue.setCharAt(1, DIGITS[(PlayerSystem.mScore% 100000) / 10000]);
mScoreValue.setCharAt(2, DIGITS[(PlayerSystem.mScore% 10000) / 1000]);
mScoreValue.setCharAt(3, DIGITS[(PlayerSystem.mScore% 1000) / 100]);
mScoreValue.setCharAt(4, DIGITS[(PlayerSystem.mScore% 100) / 10]);
mScoreValue.setCharAt(5, DIGITS[(PlayerSystem.mScore% 10)]);
mScoreText.setText(mScoreValue.toString());
but the main problem remains, .toString() is returning new object every call
Is there any way to solve this?
It sounds like a good candidate to use StringBuilder:
http://developer.android.com/reference/java/lang/StringBuilder.html
Or StringBuffer:
http://developer.android.com/reference/java/lang/StringBuffer.html
Reasoning is:
StringBuffer is used to store character strings that will be changed (String objects cannot be changed). It automatically expands as needed. Related classes: String, CharSequence.
StringBuilder was added in Java 5. It is identical in all respects to StringBuffer except that it is not synchronized, which means that if multiple threads are accessing it at the same time, there could be trouble. For single-threaded programs, the most common case, avoiding the overhead of synchronization makes the StringBuilder very slightly faster.
Edit: One thing you have to be careful of is how you use which ever SB class you pick. The reason is (same in .Net too) if you have a usage like this
StringBuilder sb = new StringBuilder(score.ToString() + "hello, world!");
You've still got 2 string concat operations, you're possibly actually making 3 strings there, one for score.ToString()
, one to turn the literal "hello, world!"
into a string, and one that contains the two concatenated together.
To get the best results, you need to use the SB's Append/insert/replace methods.
As far as I know, there is no way to get around the fact that Strings
are immutable and if your method takes a String, a new one will have to be created every time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With