我发现我的方法调用checkForErrors只需要花费大约80倍的时间才能在第一次执行时运行,而我似乎无法弄清楚原因。
D/guess: adhl
D/checkerror: checking for errors took 4760743ns // first run
D/validity: checking guess validity took 7141114ns
D/guess: agkl
D/checkerror: checking for errors took 61035ns // every other run takes around this long
D/validity: checking guess validity took 732422ns
我查看了代码,但我没有看到任何在第一次运行中需要更长时间的事情,所以我很难过。
点击监听器上的按钮:
submitBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String Guess = guess_txt.getText().toString();
Log.d("guess", Guess);
if(checkGuessValidity(Guess)){ // <--
submitValidGuess(Guess);
int bulls = game.getBullsAndHits()[0];
int hits = game.getBullsAndHits()[1];
if(!game.gameWon) //if game is not won, submit the guess with bulls and hits
guessSubmittedListener.guessSubmitted(Guess, bulls, hits);
else //if game is won, call gameWon() method
gameEnd();
}
if((game.getCurrentTry() > game.getMaxTries()) && (!Guess.equals(game.getHiddenWord()))) gameEnd(); //if user is out of tries, call gameLost method
triesLeft.setText("Tries Left: " + (game.getMaxTries() - game.getCurrentTry() + 1)); //update tries left on main fragment
guess_txt.setText("");
}
});
checkGuessValidity:
public boolean checkGuessValidity(String Guess){
long start = System.nanoTime();
long start2 = System.nanoTime();
ErrorList Status = checkForErrors(Guess); // <--
long end2 = System.nanoTime();
Log.d("checkerror", "checking for errors took " + (end2 - start2) + "ns");
. . . more code . . .
checkForErrors:
public ErrorList checkForErrors(String Guess){
if(Guess.length() != game.getHiddenWordLength()) return ErrorList.Wrong_Length;
else if(!isValidInput(Guess)) return ErrorList.Invalid_Characters;
else if(!isIsogram(Guess)) return ErrorList.Not_Isogram;
else if(!isLowercase(Guess)) return ErrorList.Not_Lowercase;
else return ErrorList.OK;
}
isValidInput,isIsogram和isLowercase:
public boolean isIsogram(String Guess){
Map<Character, Boolean> map = new HashMap();
for(int i = 0; i < Guess.length(); i++){
if(map.get(Guess.charAt(i)) == null) //if the value for the key (character) is null (has not been changed since map initialization)
map.put(Guess.charAt(i), true); //then set it to true (indicating that it has been seen)
else { //else (if the value at the character HAS been changed since initialization, ie. it has been seen)
Log.d("Character repeated", "" + Guess.charAt(i));
return false; //return false
}
}
return true; //if loop completes no duplicates were found and guess is an isogram
}
public boolean isLowercase(String Guess){
if(Guess.equals(Guess.toLowerCase())) return true;
else return false;
}
public boolean isValidInput(String Guess){
char[] chars = Guess.toCharArray();
for(int i = 0; i < chars.length; i++){
if(!isLatinLetter(chars[i])) return false;
}
return true;
}
public static boolean isLatinLetter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
似乎任何方法都不应该受到运行时的影响,因此我不知道为什么第一次执行需要额外的时间。我仍然是编程的初学者,所以请原谅任何糟糕的格式或可怕的优化代码:p。
编辑:CPU使用率图表:https://prnt.sc/ftjokq