【发布时间】:2011-10-15 23:39:15
【问题描述】:
我在 Objective-c 中实现了几乎相同的代码,它的运行速度比在 Java 中快两到三倍。我试图找出哪些指令可能是最耗费资源的指令,并看看是否有更好的方法来做同样的事情,在 Java 中更有效。
这是从数据库读取大型结果集的例程的一部分,对于返回的每个单词,它会检查该单词是否可以从玩家拥有的字母拼贴中组成。它包括对空白图块的支持,可以用作任何字母。空白图块将由下划线字符表示。
基本上,对于从数据库返回的每个单词,我都会遍历单词的每个字母,并查看可用字母的 player 数组。如果我找到那封信,我会将它从玩家数组中删除并继续前进。如果我没有找到该字母,则丢弃该单词并读取下一个单词。除非我在玩家的数组中找到下划线字符,否则我会将它用于字母,并将其从数组中删除。如果我到达数据库单词的字母数组的末尾并“找到”每个字母,那么该单词将保存在一个列表中。
我已经对整个函数的各个部分进行了计时,并且数据库查询发生得非常快。只是这个游标的处理速度很慢。任何建议将不胜感激!
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());
}
【问题讨论】:
-
" ".charAt(0)可以简单写成' ' -
你是在iphone上运行objective-c版本,在android上运行java版本吗?如果有,硬件是否有类似的速度?
-
在开始遍历每个字符之前,我会将单词字符串转换为字符数组。数组访问可能比 charAt() 更快,即使 charAt 正在做同样的事情,从堆栈中删除额外的方法调用。还为那个小花絮 +1 @Banthar,对于来自 C 代码的东西,这段代码令人惊讶地对象繁重。
-
另一个提示我总是告诉任何使用 switch 或 else if 语句的人。始终将常见情况放在首位,这些值在您的代码中似乎是按顺序排列的。如果你把共同的放在第一位,那么他们会在进行所有其他比较之前绕过路径。至少把元音放在第一位。
标签: java android performance sqlite