I have implemented almost the same code in Objective-c, and it runs two to three times faster than it does in Java. I'm trying to figure out which instructions may be the most resource intensive and see if there is a better way of doing the same thing that is more efficient in Java.
This is part of a routine that reads a large resultset from the database, and for each word that is returned, it checks to see if that word can be made from the letter tiles the player has. It includes support for blank tiles, which can be used as any letter. A blank tile will be represented by an underscore character.
Basically, for each word that is returned from the database, I iterate through each of the letters of the word, and look through the players array of available letters. If I find that letter, I remove it from the players array and keep going. If I don't find the letter, the word is discarded and the next word read. Unless, I find an underscore character in the player's array, then, I'll use that for the letter, and remove it from the array. If I get to the end of the database word's array of letters and have 'found' each one, then the word is saved in a list.
I've already timed various parts of the whole function and the database query happens pretty fast. It is just the processing of this cursor that is very slow. Any suggestions would be appreciated!
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());
}