简体   繁体   English

如何最有效地执行此递归/迭代CPU密集型android任务?

[英]How can I most efficiently execute this recursive/iterative CPU intensive android task?

Some Background Info: I have made a program that given an arraylist of letters, and an array of integers finds all the combinations of words that can exist inside this arraylist where the words length is one of the integers in the int array (wordSizes). 一些背景信息:我编写了一个给出字母数组列表的程序,一个整数数组找到了该数组列表中可以存在的所有单词组合,其中单词长度是int数组中的整数之一(wordSizes)。 ie given h, o, p, n, c, i, e, t, k and the integers 5 and 4, the solution would be: phone tick. 即给定h,o,p,n,c,i,e,t,k以及整数5和4,则解决方案是:电话打勾。

My problem right now: Inputs usually are about 25 characters and the output should usually return 5 word combinations. 我现在的问题是:输入通常约为25个字符,输出通常应返回5个单词组合。 I originally made this a console application for dekstop, and runtimes are generally less than 1 minute. 我最初将其作为dekstop的控制台应用程序,运行时间通常少于1分钟。 I decided to port it to android and runtimes reach over 35 minutes. 我决定将其移植到android,运行时超过35分钟。 I am quite a beginner and not sure about how to run a CPU intensive task on Android. 我是一个初学者,不确定如何在Android上运行CPU密集型任务。

public void findWordsLimited(ArrayList<Character> letters) {

    for (String s1 : first2s) {
        for (String s2 : possibleSeconds) {

            boolean t = true;

            String s1s2 = s1.concat(s2);
            ArrayList<Character> tempLetters = new ArrayList<Character>(letters);
            for (int i = 0; i < s1s2.length(); i++) {
                if (tempLetters.contains(s1s2.charAt(i)))
                    tempLetters.remove(Character.valueOf(s1s2.charAt(i)));
                else
                    t = false;
            }

            if (t) {
                helperFindWordsL(tempLetters, s1 + " " + s2, 2);
            }
        }
    }

}

public void helperFindWordsL(ArrayList<Character> letters, String prefix , int index) {

    boolean r;

    if (letters.size() <= 1) {
        output += "Success : " + prefix + "\n";
        Log.i(TAG, prefix);
    }

    else if (index < wordSizes.size()){

        for (String s : lastCheck) {

            if (s.length() == wordSizes.get(index)) {

                ArrayList<Character> templetters = new ArrayList<Character>(letters);
                r = true;

                for (int j = 0; j < s.length(); j++) {
                    if (templetters.contains(s.charAt(j)))
                        templetters.remove(Character.valueOf(s.charAt(j)));
                    else {
                        r = false;
                        templetters = new ArrayList<Character>(letters);
                    }
                }

                if (r)
                    helperFindWordsL(templetters, prefix + " " + s, index + 1);
            }
        }
    }

}

I am not too concerned about the algorithm, as this might be confusing because it is part of a bigger project to solve a word game puzzle. 我不太担心算法,因为这可能会引起混淆,因为它是解决文字游戏难题的更大项目的一部分。 A few questions: 几个问题:

How would I get a CPU intensive task like this finished fastest? 我如何最快完成这样的CPU密集型任务? Right now I call the method findWordsLimited() from my MainActivity. 现在,我从MainActivity中调用方法findWordsLimited()。 On my desktop app (where it says output += Success... in HelperFindWordsL) I would print all solutions to the console, but right now I have made it so that the method adds to and in the end returns a giant string (String output) back to the MainActivity, with all solutions and that String is put inside of a TextView. 在我的桌面应用程序上(它在HelperFindWordsL中显示输出+ = Success ...),我将所有解决方案打印到控制台,但是现在我已经完成了,以便该方法添加并最终返回一个巨大的字符串(字符串)输出)返回到MainActivity,并提供所有解决方案,并且将String放在TextView内。 Is that an inefficient way to display the data? 这是显示数据的低效率方法吗? If so, could you please help explain a better way? 如果是这样,请您帮忙解释一个更好的方法?

Should I be running this as a backgroud/foreground process or thread instead of just calling it from the MainActivity? 我应该将其作为背景/前台进程或线程运行,而不是仅从MainActivity调用它吗?

How can i get runtimes on my android that are currently 20x slower than my desktop faster? 我如何才能在Android上获得比台式机快20倍的运行时?

Try to replace recursion with cycles, and use arrays instead of lists, to avoid inserts etc, direct access to array members is much faster. 尝试用循环替换递归,并使用数组而不是列表,以避免插入等,直接访问数组成员要快得多。 Pay main attention to the most inner loop which uses templetters.contains(s.charAt(j)) , optimization of this part of code will give main effect. 要特别注意使用templetters.contains(s.charAt(j))的最内层循环,这部分代码的优化将产生主要效果。

You may add break; 您可以添加break; after t = false; t = false;

String s1s2 = s1.concat(s2); - it's not good to create a new String object for such case - it makes unnecessary work for GC . -在这种情况下创建一个新的String对象是不好的-这会使GC不必要的工作。 I would replace it with 2 cycles through s1 then s2 我将其替换为s1 s2 2个周期

You could use 'letters' instead of ArrayList<Character> tempLetters = new ArrayList<Character>(letters); 您可以使用“字母”代替ArrayList<Character> tempLetters = new ArrayList<Character>(letters); , just marking some items there as deleted. ,只需将其中的某些项目标记为已删除。 No need to create local clones. 无需创建本地克隆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM