Java方法在首次运行时运行速度非常慢(Android)

时间:2017-07-09 17:19:59

标签: java android performance

我发现我的方法调用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

0 个答案:

没有答案