I need a little assistance regarding my algorithm. I have tried to look for similar questions but couldn't find something that would satisfy me.
I have code that executes very fast (0.3s) in my desktop but when deployed on Android device (not emulator, Samsung S3) it executes really slow, it can take up to a one minute. I would like to know what possibilities do I have to make it run a lot faster, say under 1s.
I have read that heavy recursion in Android can cause memory allocation / GC issues, can it be the case here? How to avoid it? Go iterative?
Code is here:
public class CombinationsQuestion {
public static void main(String[] args) {
CombinationsQuestion comb = new CombinationsQuestion();
long start = new Date().getTime();
List<String> combinations = comb.combinations("12345678".toCharArray());
long end= new Date().getTime();
for(String s : combinations) {
System.err.println(s);
}
System.err.println(combinations.size());
System.err.println("took " + (end - start) + " ms");
}
public List<String> combinations(char[] word) {
List<String> list = new ArrayList<String>();
if (word.length == 1) {
list.add(String.valueOf(word));
} else {
char[] sub = new char[word.length - 1];
for (int i = 0; i < word.length; i++) {
System.arraycopy(word, 0, sub, 0, i);
System.arraycopy(word, i + 1, sub, i, sub.length - i);
list.add(String.valueOf(word[i]));
list.addAll(concatenate(word[i], combinations(sub)));
}
sub = null;
}
return list;
}
public List<String> concatenate(char c, final List<String> lst) {
List<String> ret_set = new ArrayList<String>(lst.size());
for (String s : lst) {
ret_set.add(c + s);
}
return ret_set;
}
}
Could I solve it by temporarily allocating a bigger stack like Android: Increase call stack size?
Thank you in advance!
ps. I know this produces a lot of Strings.
-- update --
I debugged the code and it seems that Dalvik is doing heavy GC during the recursion. This does not happen on regular desktop.
So the only way of doing this is trying to reuse the variables and not to instantiate objects so many. Of course this is a bit tricky when producing Strings but you can use StringBuilder / StringBuffer to some extent.
I found an article saying using NDK could solve this problem but adding NDK code adds complexity to the project and I was not willing (yet) to go that road.