Java - 什么可以使这段代码运行得更快?

Mic*_*gan 2 java sqlite performance android

我在Objective-c中实现了几乎相同的代码,它的运行速度比Java快两到三倍.我正在试图找出哪些指令可能是最耗费资源的,并且看看是否有更好的方法来做同样的事情,这在Java中更有效.

这是从数据库中读取大型结果集的例程的一部分,对于返回的每个单词,它会检查该单词是否可以从播放器具有的字母区块中创建.它包括对空白图块的支持,可以用作任何字母.空白图块将由下划线字符表示.

基本上,对于从数据库返回的每个单词,我遍历单词的每个字母,并查看可用字母的玩家数组.如果我找到那封信,我将其从玩家阵列中移除并继续前进.如果我没有找到该字母,则该字被丢弃并且下一个字被读取.除非,我在播放器的数组中找到一个下划线字符,然后,我将使用它作为字母,并将其从数组中删除.如果我到达数据库字的字母数组的末尾并且每个字母都"找到",那么该单词将保存在列表中.

我已经计时了整个函数的各个部分,数据库查询发生得非常快.这只是对这个游标的处理非常慢.任何建议,将不胜感激!

if (c.moveToFirst()) {

    do { 
        boolean found = false;
        int aValue = 0;
        int letterValue = 0;

        // Word and Word's length from the database
        String sWord = c.getString(0);
        int wordLength = c.getInt(1);

        // Refresh the Tile array, underscores sorted to the front
        // sortedTiles sorted the players tiles {_,_,a,b,c}
        char[] aTiles = sortedTiles.clone();

        // Calculate the value of the word
        for (int i = 0; i < wordLength; i++) {

            // For each character in the database word
            switch (sWord.charAt(i)) {
            case 97:
                letterValue = 1;
                break;
            case 98:
                letterValue = 4;
                break;
            case 99:
                letterValue = 4;
                break;
            case 100:
                letterValue = 2;
                break;
            case 101:
                letterValue = 1;
                break;
            case 102:
                letterValue = 4;
                break;
            case 103:
                letterValue = 3;
                break;
            case 104:
                letterValue = 3;
                break;
            case 105:
                letterValue = 1;
                break;
            case 106:
                letterValue = 10;
                break;
            case 107:
                letterValue = 5;
                break;
            case 108:
                letterValue = 2;
                break;
            case 109:
                letterValue = 4;
                break;
            case 110:
                letterValue = 2;
                break;
            case 111:
                letterValue = 1;
                break;
            case 112:
                letterValue = 4;
                break;
            case 113:
                letterValue = 10;
                break;
            case 114:
                letterValue = 1;
                break;
            case 115:
                letterValue = 1;
                break;
            case 116:
                letterValue = 1;
                break;
            case 117:
                letterValue = 2;
                break;
            case 118:
                letterValue = 5;
                break;
            case 119:
                letterValue = 4;
                break;
            case 120:
                letterValue = 8;
                break;
            case 121:
                letterValue = 3;
                break;
            case 122:
                letterValue = 10;
                break;
            default:
                letterValue = 0;
                break;
            } // switch

            found = false;

            // Underscores will be sorted to the front of the array, 
            // so start from the back so that we give
            // real letters the first chance to be removed.
            for (int j = aTiles.length - 1; j > -1; j--) {
                if (aTiles[j] == sWord.charAt(i)) {
                    found = true;
                    // Increment the value of the word
                    aValue += letterValue;

                    // Blank out the player's tile so it is not reused
                    aTiles[j] = " ".charAt(0);

                    // I was removing the element from the array
                    // but I thought that might add overhead, so
                    // I switched to just blanking that letter out
                    // so that it wont be used again
                    //aTiles = removeItem(aTiles, j);

                    break;
                }

                if (aTiles[j] == cUnderscore) {
                    found = true;

                    // Blank out the player's tile so it is not reused
                    aTiles[j] = " ".charAt(0);

                    // I was removing the element from the array
                    // but I thought that might add overhead, so
                    // I switched to just blanking that letter out
                    // so that it wont be used again
                    //aTiles = removeItem(aTiles, j);
                    break;
                }

            } // for j

            // If a letter in the word could not be fill by a tile 
            // or underscore, the word doesn't qualify
            if (found == false) {
                break;
            }

        } // for i

        // If all the words letters were found, save the value and add to the list.
        if (found == true) {

            // if all the tiles were used it's worth extra points
            String temp = aTiles.toString().trim();

            if (temp.length() < 1) {
                aValue += 35;
            }

            Word word = new Word();
            word.word = sWord;
            word.length = wordLength;
            word.value = aValue;
            listOfWords.add(word);
        }

    } while (c.moveToNext());
}
Run Code Online (Sandbox Code Playgroud)

Ted*_*opp 8

我不知道您的代码在大部分时间内的确切位置.你应该描述一下.但我会用表查找替换你的long switch语句:

// In the class:
private static final int[] letterValues = {
    1, 4, 4, 2, 1, // etc.
}

// In the code:

// Calculate the value of the word
for (int i = 0; i < wordLength; i++) {

    // For each character in the database word
    char ch = sWord.charAt(i);
    if (ch >= 97 && ch <= 122) {
        letterValue = letterValues[ch - 97];
    } else {
        letterValue = 0;
    }

    // the rest of your code
Run Code Online (Sandbox Code Playgroud)

这可能比switch语句快得多.

编辑:我注意到你的j循环内部正在调用sWord.charAt(i)每个j值.通过将函数调用分解出循环,可以加快速度.如果您使用我的代码,您可以使用ch代替sWord.charAt(i).

PS作为一种风格,代码if (found) { ...而不是代码更好if (found == true) { ....同样使用if (!found) {而不是if (found == false) {.