Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String and Garbage Collection

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?

like image 874
Paweł Avatar asked Dec 28 '22 15:12

Paweł


2 Answers

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.

like image 73
Russ Clarke Avatar answered Jan 09 '23 04:01

Russ Clarke


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.

like image 35
Daniel Avatar answered Jan 09 '23 04:01

Daniel