I'm currently refactoring some old code of mine that I had done a few years ago, where it takes in two Lists to compare their contents, and then return the mapped contents that were matched. With 750 items for potential needles, and over 25000 items as the haystack, the original code took about 22-25 seconds to process. After a bit of refactoring however I was able to reduce it to just over a second. Is there a way to improve it further?
Here's the original code
Map<String, ArrayList<TreeMap<String, String>>> map = new TreeMap<String, ArrayList<TreeMap<String, String>>>(); String charsToFilter = "[" + Pattern.quote("_-") + "]"; for (int i = 0 ; i < baseDataArray.size() ; i++) { String currentProduct = baseDataArray.get(i).get("product_name").replaceAll(charsToFilter, " ").toLowerCase(); for (int j = 0 ; j < inventoryArray.size() ; j++) { String currentListing = inventoryArray.get(j).get("title").replaceAll(charsToFilter, " ").toLowerCase(); if (currentListing.contains(currentProduct)) { ArrayList<TreeMap<String, String>> currentListingArray = new ArrayList<TreeMap<String, String>>(); TreeMap<String, String> currentListingMap = new TreeMap<String, String>(); for (Map.Entry<String, String> keyValue : inventoryArray.get(j).entrySet()) { currentListingMap.put(keyValue.getKey(), keyValue.getValue()); } currentListingArray.add(currentListingMap); if (map.get(currentProduct) == null) { map.put(currentProduct, currentListingArray); } else { map.get(currentProduct).add(currentListingMap); } } } } return map;
And here's the new code:
Map<String, ArrayList<TreeMap<String, String>>> map = new TreeMap<String, ArrayList<TreeMap<String, String>>>();
String charsToFilter = "[" + Pattern.quote("_-") + "]";
ArrayList<String> productNameArray = new ArrayList<String>();
for (Map<String, String> baseDataItem : baseDataArray) {
productNameArray.add(baseDataItem.get("product_name")
.replaceAll(charsToFilter, " ").toLowerCase());
}
for (Map<String, String> inventoryItem : inventoryArray) {
//moving this to the for loop below increase execution time by 100%
String processedInventoryItem = inventoryItem.get("title").replaceAll(charsToFilter, " ").toLowerCase();
for (String productName : productNameArray) {
if (processedInventoryItem.contains(productName)) {
ArrayList<TreeMap<String, String>> currentListingArray = new ArrayList<TreeMap<String, String>>();
TreeMap<String, String> currentListingMap = new TreeMap<String, String>();
for (Map.Entry<String, String> keyValue : inventoryItem.entrySet()) {
currentListingMap.put(keyValue.getKey(), keyValue.getValue());
}
currentListingArray.add(currentListingMap);
if (map.get(productName) == null) {
map.put(productName, currentListingArray);
} else {
map.get(productName).add(currentListingMap);
}
break;
}
}
}
return map;
There's some differences such as going from for
to foreach
loops, but nothing that I can see that would make such a change. Anyone have any thoughts on how to improve it further, or why it has come so far already.