Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使此代码更高效? public-double-getRating(长userID、长movieID){ 双答案=-1; 对于(int i=0;i_Java_Performance - Fatal编程技术网

Java 如何使此代码更高效? public-double-getRating(长userID、长movieID){ 双答案=-1; 对于(int i=0;i

Java 如何使此代码更高效? public-double-getRating(长userID、长movieID){ 双答案=-1; 对于(int i=0;i,java,performance,Java,Performance,我已经格式化了数据行,所以我想检查这些行中某个位置的数据是否等于传入的userID和movieID,如果是,我将在第二个元素返回数据。我的问题可能是通过tab键分割数据行,但我想不出更有效的方法,可能使用indexOf,但如果使用indexOf,它还将显示时间戳中是否有用户ID或电影ID,这将是一个坏错误。有人能给我一些更快的建议吗?我强调了几种优化方法,可能还有其他方法: public double getRating(long userID, long movieID) {

我已经格式化了数据行,所以我想检查这些行中某个位置的数据是否等于传入的userID和movieID,如果是,我将在第二个元素返回数据。我的问题可能是通过tab键分割数据行,但我想不出更有效的方法,可能使用indexOf,但如果使用indexOf,它还将显示时间戳中是否有用户ID或电影ID,这将是一个坏错误。有人能给我一些更快的建议吗?

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

    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;
}
public-double-getRating(长userID、长movieID){
双答案=-1;
字符串[]temp=null;//很适合在循环外部分配数据
int length=ratingLineData.length;//良好实践
for(int i=0;i
我只能看到一个明显的优化,它避免了额外的长->双转换:

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;
}
public-double-getRating(长userID、长movieID){
双答案=-1;
对于(int i=0;i
即使如此,我还是会测量它来确定

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

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

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;
}
public long getRating(long userID,long movieID){
字符串um=userID+“\t”+movieID+“\t”;
对于(int i=0;i
解析最有效的代码应该只迭代所有字符一次,而不应该分配新内存。换句话说,您只需要这样一个状态机:

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;
}
CharSequence[]ratingLineData=新字符串[]{“10\t1\t300”、“10\t2\t400”、“20\t1\t100”};
公共双getRating(长用户ID、长电影ID){
对于(int i=0;i

这个例子说明了以下原理。如果有人要求使用最有效的代码进行解析,答案是构建一个特定的状态机。

我认为这不会有多大区别。。。我建议您通过在第一次查询期间将数据存储在某个映射中,来提高以后调用
getRating
的性能。这样,您以后的查询会快速进行,而不是一次又一次地从文件中重新读取。在程序运行过程中,
getRating
是否会多次被调用?您能否向我们展示
ratingLineData
数组?这真的很有帮助。是的,ratingLineData被调用20000次,它是一个.data文件,格式为“userID\t movieID\t starting\t timestamp\n”。正如在它的例子中,由制表符空格分隔的4条数据。我不认为int length=ratingLineData.length;//良好的实践会带来很大的不同,因为它是属性,而不是函数调用,如果ratingLineData是字符串,则int length=ratingLineData.length();应该在外部使用。另外,在循环外部声明temp也没有帮助,因为字符串[]无论如何每次迭代都会创建一次。恰恰相反:在最内部的可能上下文中声明是首选的编码实践。long-double只发生一次。解析long时为什么不返回long呢?既然我现在不在,我会在几个小时后尝试这个方法,但这似乎是可行的
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));