Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.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/1/ms-access/4.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 如何优化这个嵌套for循环?_Java_Ms Access_Optimization - Fatal编程技术网

Java 如何优化这个嵌套for循环?

Java 如何优化这个嵌套for循环?,java,ms-access,optimization,Java,Ms Access,Optimization,我创建了一个在我的计算机上运行良好的方法(大约需要4秒钟才能完成)。但是,最终用户将在远程桌面环境中使用该方法,在远程桌面环境中,相同的请求需要25-50秒才能完成。如何优化此程序 private void compareAndPopulateArrays(List<String> listOfGenIdsFromXml, List<String> listOfGenIdsFromDB, String dburl) throws Class

我创建了一个在我的计算机上运行良好的方法(大约需要4秒钟才能完成)。但是,最终用户将在远程桌面环境中使用该方法,在远程桌面环境中,相同的请求需要25-50秒才能完成。如何优化此程序

private void compareAndPopulateArrays(List<String> listOfGenIdsFromXml,
        List<String> listOfGenIdsFromDB, String dburl)
        throws ClassNotFoundException, SQLException {
    mdbAccessor = new MDBAccessor();
    for (int x = 0; x < listOfGenIdsFromXml.size(); x++) {
        Boolean matching_id_found = false;
        for (int y = 0; y < listOfGenIdsFromDB.size(); y++) {
            if (listOfGenIdsFromXml.get(x)
                    .equals(listOfGenIdsFromDB.get(y)) || equalsLanguageCodeIgnore(listOfGenIdsFromXml.get(x),listOfGenIdsFromDB.get(y))) {
                addNewMatchingRecognition(listOfGenIdsFromXml,
                        listOfGenIdsFromDB, dburl, x, y);
                matching_id_found = true;
            }
        }
        if (!(matching_id_found == true)) {
            newRecognitions.add(new NewRecognition(listOfGenIdsFromXml
                    .get(x)));
        }
    }
}
    private void addNewMatchingRecognition(List<String> listOfGenIdsFromXml,
        List<String> listOfGenIdsFromDB, String dburl, int x, int y)
        throws ClassNotFoundException, SQLException {
    String gen_id_Xml = listOfGenIdsFromXml.get(x);
    String gen_id_DB = listOfGenIdsFromDB.get(y);
    int issue_id = mdbAccessor.getIssueId(gen_id_DB, dburl);
    String issue_expression = mdbAccessor.getIssueExpression(gen_id_DB,
            dburl);
    String issue_detail = mdbAccessor.getIssueDetails(gen_id_DB, dburl);
    matchingRecognitions.add(new MatchingRecognition(gen_id_Xml, gen_id_DB,
            issue_id, issue_detail, issue_expression));
}
EqualLanguageCodeIgnore:

    public boolean equalsLanguageCodeIgnore(String gen_id, String gen_id_DB) {
    if (genIdsAreEqualMinusLanguageCode(gen_id, gen_id_DB)) {
        return true;
    } else {
        return false;
    }
}

private boolean genIdsAreEqualMinusLanguageCode(String gen_id,
        String gen_id_DB) {
    return gen_id_DB.contains("P-XX-")
            && gen_id.substring(5).equals(gen_id_DB.substring(5));
}
新的和改进的MDBAccessor类:

public class MDBAccessor {
private Connection connection;
private Statement statement;

public void setupConnection(String dburl)
        throws ClassNotFoundException, SQLException {
        connection = DriverManager
            .getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq="
                    + dburl);
        statement = connection.createStatement();
}

public void closeConnection() throws SQLException{
    connection.close();
}
////
public int getIssueId(String gen_id) throws ClassNotFoundException,
            SQLException {
        ResultSet resultSet = statement
                .executeQuery("SELECT issue_id FROM es_it WHERE gen_id='&&"
                        + gen_id + "' OR gen_id='&" + gen_id + "'");

        if (resultSet.next()){
            int getint = resultSet.getInt(1);
            resultSet.close();
            return getint;
        }else{
            resultSet.close();
            return -1;
        }
    }
  • 获取项目一次,然后传递项目,而不是列表和索引。这将限制在列表中进行的查找的数量,我认为这是相当大的。根据您的Java版本,您可能希望使用一个可读性构造
  • 我希望您可以将数据库访问整合到单个查询中,这样可以节省时间

    int issue_id=mdbAccessor.getIssueId(gen_id_DB,dburl); 字符串issue\u expression=mdbAccessor.getIssueExpression(gen\u id\u DB, dburl); 字符串issue\u detail=mdbAccessor.getIssueDetails(gen\u id\u DB,dburl)

  • 您似乎正在为每个查询打开和关闭数据库。打开它一次,并在函数结束时关闭它,因为打开和关闭DB连接的成本很高(特别是针对访问IIRC)。您可能希望使连接对象成为
    MDBAccessor
    类的成员。请记住使用构造以确保其已关闭


  • 建议进行重构以提高可读性

    private void compareAndPopulateArrays(List<String> xmlGenIds,
            List<String> dbGenIds, String dbUrl)
            throws ClassNotFoundException, SQLException {
        //Better yet move it into an init method or the class constructor
        mdbAccessor = new MDBAccessor(dbUrl);
        for (String currXmlId : xmlGenIds) {
            Boolean matchingIdFound = false;
            for (String currDbId : dbGenIds) {
                if (currXmlId.equals(currDbId) || 
                        equalsLanguageCodeIgnore(currXmlId,currDbId)) {
                    addNewMatchingRecognition(currDbId, currXmlId);
                    matchingIdFound = true;
                }
            }
            if (!matchingIdFound) {
                newRecognitions.add(new NewRecognition(currDbId));
            }
        }
    }
    
    private void compareandpopulatearray(列出xmlGenIds,
    列表dbGenIds,字符串dbUrl)
    抛出ClassNotFoundException、SQLException{
    //最好将其移动到init方法或类构造函数中
    mdbAccessor=新的mdbAccessor(dbUrl);
    for(字符串currXmlId:xmlGenIds){
    布尔匹配IDFound=false;
    for(字符串currDbId:dbGenIds){
    如果(currXmlId.equals(currDbId)|
    equalLanguageCodeIgnore(currXmlId,currDbId)){
    addNewMatchingRecognition(currDbId、currXmlId);
    matchingIdFound=true;
    }
    }
    如果(!matchingIdFound){
    newRecognitions.add(newnewrecognitions(currDbId));
    }
    }
    }
    
    您可以尝试从listOfGenIdsFromDB中缩短一些哈希映射,并用映射查找替换内部循环,这将减少重复迭代listOfGenIdsFromDB的需要。

    Emil您能告诉我您使用的Java版本是什么吗,您正在迭代的两个列表有多大?同时,为了可读性,这段代码需要一些真正的重构。EqualLanguageCodeIgnore方法是什么?如果可能,首先显示代码确保延迟确实是由您的方法引起的。在远程桌面环境中,您的方法也可能在4秒内完成,但由于某些其他原因,需要50秒才能显示在用户屏幕上。当通过rdp执行时,尝试测量方法的运行时(即通过在方法之前和之后调用System.nanoTime()),并显示时间。然后,如果你确信“这种方法确实是一个瓶颈,那么按照其他海报答案中给出的建议去做(特别是C.Ross提到的开始/结束问题似乎很有希望)。@C.Ross:Java 1.6,它们大约有500-1000个条目。如果有人能将代码格式化到列表中,我将不胜感激it@C.罗斯希望我知道。。。使用反勾号强制设置代码格式将重置列表计数器(3.变为1.):(非常感谢您的回复!今天我会在有时间的时候尝试一下。我做了重构,现在可读性更好了,而且它也减少了一些处理时间,谢谢。至于第3部分,我想我还有一些阅读要做。您能告诉我这个()是否是这个问题的合适来源吗?我按照您的解释做了,添加了连接和语句作为类的成员,在init()方法中初始化了它们,并在我放在函数末尾的closeConnection()方法中关闭了连接。这将处理时间从25秒缩短到2秒!非常感谢。您可能需要注意,他们可能需要实现一个自定义比较器(以处理
    equallanguageCodeIgnore
    )。不要势利,但我认为这可能有点超出了用户的知识范围。一切都取决于EqualLanguageCodeIgnore方法的实现。如果这个方法只是为每个参数生成一个值并进行比较,那么就有可能为这些值维护额外的映射。这导致用两张地图替换内环。是的,他还没有提供更多信息。非常感谢你的回复。我也有这个想法,虽然C.Ross说我没有那么多经验是正确的,但我认为这可以很容易地完成,因为你会看到EqualLanguageCodeIgnore方法(添加在原始文章的底部)非常简单。我们稍后也会检查这个!我想做这个改变会减少更多的处理时间?我有时间的时候会调查的。非常感谢。
    private void compareAndPopulateArrays(List<String> xmlGenIds,
            List<String> dbGenIds, String dbUrl)
            throws ClassNotFoundException, SQLException {
        //Better yet move it into an init method or the class constructor
        mdbAccessor = new MDBAccessor(dbUrl);
        for (String currXmlId : xmlGenIds) {
            Boolean matchingIdFound = false;
            for (String currDbId : dbGenIds) {
                if (currXmlId.equals(currDbId) || 
                        equalsLanguageCodeIgnore(currXmlId,currDbId)) {
                    addNewMatchingRecognition(currDbId, currXmlId);
                    matchingIdFound = true;
                }
            }
            if (!matchingIdFound) {
                newRecognitions.add(new NewRecognition(currDbId));
            }
        }
    }