上下文
我编写了一个小型Java应用程序,用于从Oracle到Microsoft的数据迁移的基本测试。
该应用程序执行以下操作:
问题
我遇到的问题是比较我拥有的两个String数组(Oracle Rows和Microsoft Rows)。 对于某些表,可能有近一百万行数据。虽然我的当前代码可以在几秒钟内将1000个Oracle行与Microsoft的行匹配 - 但时间会增加。
当前尝试修复问题
观
代码
numRowsOracle = oracleTable.getRows().size();
numRowsMicrosoft = msTable.getRows().size();
int orRowCounter = 0;
boolean matched;
// Each Oracle Row
for (String or : oracleTable.getRows()) {
matched = false;
orRowCounter++;
if (orRowCounter % 1000 == 0) {
System.out.println("Oracle Row: " + orRowCounter + " / "
+ numRowsOracle);
}
// Each Microsoft Row
for (String mr : msTable.getRows()) {
if (mr.equalsIgnoreCase(or)) {
matched = true;
break;
}
}
if (!matched) { // Adding row to list of unmatched
unmatchedRowStrings.add(or);
}
}
// Writing report on table.
exportlogs.writeTableLog(td.getTableName(), unmatchedRowStrings
.size(), unmatchedRowStrings, numRowsOracle,
numRowsMicrosoft);
}
有关如何加快速度的任何建议?我接受的想法不仅是加快比较两个数组,而且还以不同的方式存储数据。我没有使用其他类型的String存储,例如hashmaps。不同的东西会更快吗?
答案 0 :(得分:2)
这是未经测试的,所以请加上一点盐,特别是如果你使用的是非ascii字符。
您可以在一次传递中对数据进行小写(或大写)验证,然后使用哈希集来验证它们。
// make a single pass over oracle rows, so O(n)
Set<String> oracleLower = new HashSet<>();
for(String or : oracleTable.getRows()) {
oracleLower.add(or.toLowerCase());
}
// make a single pass over msft rows, so O(n)
Set<String> msftLower = new HashSet<>();
for(String ms : microsoftTable.getRows()) {
msftLower.add(ms.toLowerCase());
}
// make a single pass over oracle rows, again O(n)
for(String or : oracleLower) {
// backed by a hash table, this has a constant time lookup
if(!msftLower.contains(or)) {
unmatched.add(or);
}
}
由于哈希表,每个操作都是O(n)。但这需要双倍的空间要求。优化可能是必要的,只能使一个集合小写(可能是msft)并且只在循环中使另一个(可能是oracle)小写 - 然后它更像for(String or : oracleTable.getRows()) { or = or.toLowerCase(); if(!msftLower.contains(or)) { ... } }