如何使此代码更有效?

时间:2015-02-04 05:45:12

标签: java performance

    public double getRating(long userID, long movieID) {

    double answer = -1;

    for(int i = 0; i < ratingLineData.length; i++){
        String[] temp = ratingLineData[i].split("\t");
        if(Long.parseLong(temp[0]) == userID && Long.parseLong(temp[1]) == movieID)
            return Long.parseLong(temp[2]);
    }



    return answer;
}

我已经格式化了数据行,因此我想检查这些行的某个位置的数据是否等于传入的userID和movieID,如果是,我将返回数据第二个元素。我的问题可能是我通过tab键分割数据行的地方,但是我无法想到任何更有效的东西,可能使用indexOf,但是如果我使用indexOf那么它也会显示是否有用户&#39 ;时间戳中的ID或电影ID,这将是一个错误的错误。有人能给我指点什么会更快吗?

4 个答案:

答案 0 :(得分:0)

我强调了几种优化方法,也可能还有其他方法:

public double getRating(long userID, long movieID) {

double answer = -1;
String[] temp = null; // Good to assign data outside the loop
int length = ratingLineData.length; // good practice

for(int i = 0; i < length; i++){
    temp = ratingLineData[i].split("\t");
    if(Long.parseLong(temp[0]) == userID && Long.parseLong(temp[1]) == movieID)
        return Long.parseLong(temp[2]);
}

return answer;
}

答案 1 :(得分:0)

我只能看到一个明显的优化,这可以避免额外的长 - &gt;双转换:

public double getRating(long userID, long movieID) {

    double answer = -1;

    for(int i = 0; i < ratingLineData.length; i++) {
        String[] temp = ratingLineData[i].split("\t");
        if(Long.parseLong(temp[0]) == userID && Long.parseLong(temp[1]) == movieID)
            return Double.parseDouble(temp[2]);
    }
    return answer;
}

即使这样,我也会测量它。

String[] temp声明移出循环不太可能有任何区别,因为它不会导致对象分配。

答案 2 :(得分:0)

假设(!)ratingLineData格式正确,您可以将两个ID匹配为字符串,并仅转换评级(如果匹配)。如果有很多搜索,排序和二分搜索将大大改善问题。

public long getRating(long userID, long movieID) {
  String um = userID + "\t" + movieID + "\t";
  for(int i = 0; i < ratingLineData.length; i++){
    if( ratingLineData[i].startsWith( um ) ){
      return Long.parseLong( ratingLineData[i].substring( um.length() ));
    }
  }
  return -1L;
}

答案 3 :(得分:0)

解析的最有效代码应该只迭代所有字符一次,并且不应该分配新内存。换句话说,你只需要一个这样的状态机:

CharSequence[] ratingLineData = new String[]{"10\t1\t300", "10\t2\t400", "20\t1\t100"};

public double getRating(long userID, long movieID) {
    for (int i = 0; i < ratingLineData.length; i++) {
        final CharSequence line = ratingLineData[i];

        long currentUserID = 0;
        long currentMovieID = 0;
        long currentRating = 0;
        int currentColumn = 0;

        for (int j = 0; j < line.length(); j++) {
            final char c = line.charAt(j);
            switch (c) {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    final int digit = c - '0';
                    switch (currentColumn) {
                        case 0:
                            currentUserID = currentUserID * 10 + digit;
                            break;
                        case 1:
                            currentMovieID = currentMovieID * 10 + digit;
                            break;
                        case 2:
                            currentRating = currentRating * 10 + digit;
                            break;
                    }
                    break;
                case '\t':
                    currentColumn++;
                    break;
                default:
                    break;
            }
        }
        if (currentUserID == userID && currentMovieID == movieID) {
            return currentRating;
        }
    }

    return -1;
}

System.out.println(getRating(5, 3));
System.out.println(getRating(10, 2));        
System.out.println(getRating(20, 1));
System.out.println(getRating(20, 2));

此示例说明了以下原则。如果有人要求最有效的解析代码,那么答案就是构建一个特定的状态机。