递归需要很长时间,Android

递归需要很长时间,Android,android,performance,recursion,Android,Performance,Recursion,关于我的算法,我需要一些帮助。我试图寻找类似的问题,但找不到能让我满意的东西 我的桌面上有执行速度非常快(0.3秒)的代码,但部署在Android设备(不是emulator,三星S3)上时,执行速度非常慢,可能需要一分钟的时间。我想知道我有什么可能使它运行得更快,比如在1秒以下 我已经读到Android中的重递归会导致内存分配/GC问题,这里会是这种情况吗?如何避免呢?去迭代 代码如下: public class CombinationsQuestion { public static voi

关于我的算法,我需要一些帮助。我试图寻找类似的问题,但找不到能让我满意的东西

我的桌面上有执行速度非常快(0.3秒)的代码,但部署在Android设备(不是emulator,三星S3)上时,执行速度非常慢,可能需要一分钟的时间。我想知道我有什么可能使它运行得更快,比如在1秒以下

我已经读到Android中的重递归会导致内存分配/GC问题,这里会是这种情况吗?如何避免呢?去迭代

代码如下:

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;
}

}
公共类组合问题{
公共静态void main(字符串[]args){
CombinationsQuestion comb=新的CombinationsQuestion();
长启动=新日期().getTime();
列表组合=comb.combines(“12345678.toCharArray());
long end=new Date().getTime();
用于(字符串s:组合){
系统错误打印项次;
}
System.err.println(combinations.size());
System.err.println(“take”+(end-start)+“ms”);
}
公共列表组合(字符[]字){
列表=新的ArrayList();
if(word.length==1){
list.add(String.valueOf(word));
}否则{
char[]sub=新字符[word.length-1];
for(int i=0;i
我可以临时分配一个更大的堆栈来解决这个问题吗

提前谢谢你

我知道这会产生很多字符串

--更新--

我调试了代码,似乎Dalvik在递归过程中执行了大量GC。这不会发生在普通桌面上

这样做的唯一方法是尝试重用变量,而不是实例化太多的对象。当然,在生成字符串时这有点棘手,但在某种程度上可以使用StringBuilder/StringBuffer


我发现一篇文章说,使用NDK可以解决这个问题,但添加NDK代码会增加项目的复杂性,我(还)不愿意这样做。

你必须打印整个集合吗?如果没有,您可以使用标准排列公式,它应该运行得更快

    /**
     * The setSize in the question's example would be 8 since there are 8 possible numbers 
     * to choose from in the set "12345678"
     */
    public static void solvePermutation(int setSize){
       long p = 0;
       for(int subSet=1; subSet<setSize+1; subSet++){
        p = p + permutation(setSize,subSet);
       }
       System.out.println(p);
   }

/**
 * p(n,r)  =  n!/((n-r)!) 
 * http://www.calctool.org/CALC/math/probability/combinations
 * 
 * @param n set size
 * @param r subset size
 * @return
 */
public static long permutation(long n, long r){
    long p = factorial(n)/
            (factorial(n-r));
    return p;
}

/**
 * http://stackoverflow.com/a/7879559/1361695
 * 
 * @param n
 * @return
 */
public static long factorial(long n) {
    long fact = 1; // this  will be the result
    for (long i = 1; i <= n; i++) {
        fact *= i;
    }
    return fact;
}
/**
*问题示例中的setSize为8,因为有8个可能的数字
*从集合“12345678”中选择
*/
公共静态置换(int-setSize){
长p=0;

对于(int subSet=1;subSet他在哪里使用置换?@aaronrod我需要将它们存储在一个数据结构中,以便以后使用,因此仅在函数内部打印它们对我不起作用。@mikeyaworski这只是一个递归速度慢的示例,实际示例并没有这样使用。我根据实现h将其转换为迭代以前和现在都降到了6秒,这是原来的十分之一,非常好。但这仍然需要很长时间,我仍然不知道如何使速度更快。我肯定不知道是什么导致了“缓慢”。是的,我的答案只给出了一种可能的排列解决方案。你是否考虑过在应用程序中附带一个预填充的db?。只是告诉大家,增加堆栈大小根本没有帮助。如果你可以避免使用递归,那么递归需要内存。我是否正确理解你的代码,它会为给定的集合生成所有可能的数字f字符?在您提到的另一条评论中,您需要将所有结果存储在某个地方供以后使用。这是一个可随机访问的列表还是一个
迭代器就足够了?@jboi我也尝试过迭代器解决方案,但没有产生任何更好的结果。我认为这两种解决方案中的问题都是代码产生了大量字符串,在生成字符串时,GC尝试释放内存,这会导致Dalvik to GC_并发延迟实际执行。