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,这将是一个错误的错误。有人能给我指点什么会更快吗?
答案 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));
此示例说明了以下原则。如果有人要求最有效的解析代码,那么答案就是构建一个特定的状态机。