I created a method that works Just Well Enough (takes ~4 seconds to complete) on my computer. However, the end user will use the method in a remote-desktop environment, where the same request took anything from 25-50 seconds to complete. How can I optimize this program?
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));
}
And all the mdbAccessor methods look similarly to the following:
public int getIssueId(String gen_id, String dburl) throws ClassNotFoundException,
SQLException {
Connection connection = setupConnection(dburl);
Statement statement = connection.createStatement();
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();
connection.close();
return getint;
}else{
resultSet.close();
connection.close();
return -1;
}
}
equalsLanguageCodeIgnore:
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));
}
New and improved MDBAccessor class:
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;
}
}
I expect you could consolidate the database accesses into a single query, which would save time.
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);
You seem to be opening and closing the DB for each query. Open it once, and close it at the end of the function, as the open and close of the DB connection is costly (especially against Access IIRC). You would likely want to make the connection object a member of your
MDBAccessorclass. Remember to use a try finally construct to ensure it is closed.Suggested refactoring for readability