Reputation: 1015
I have written a simple java class to perform part of a search on my data store, but when I ran it against my consecutive version the execution times were slower.
Consecutive Search took 11 milliseconds Concurrent Search took 23 milliseconds
I have never written a threaded application, I was hoping it would be a pretty simple operation. Can someone point me in the right direction with this code snippet. Be brutal as I have no idea!
public class ExecuteManager {
private Store store;
private ArrayList<ArrayList<UUID>> entityKeys;
public ExecuteManager(Store store){
this.store = store;
this.entityKeys = new ArrayList<ArrayList<UUID>>();
}
// Returns a list of uuids that should be collected
public ArrayList<ArrayList<UUID>> run(UUID entityTypeKey, ArrayList<WhereClauseAbstract> whereClauseList) throws InterruptedException{
ArrayList<SearchThread> queryParts = new ArrayList<SearchThread>();
for (WhereClauseAbstract wc: whereClauseList){
SearchThread st = new SearchThread(entityTypeKey, wc);
st.start();
st.join();
queryParts.add(st);
}
return entityKeys;
}
public class SearchThread extends Thread {
private UUID entityTypeKey;
private WhereClauseAbstract whereClause;
public SearchThread(UUID entityTypeKey, WhereClauseAbstract whereClause){
this.entityTypeKey = entityTypeKey;
this.whereClause = whereClause;
}
public void run(){
// Run search and add to entity key list
entityKeys.add(
store.betterSearchUuid2(entityTypeKey, whereClause.getField(), whereClause.getOperator())
);
}
}
}
Upvotes: 0
Views: 200
Reputation: 533520
You have to be careful that the overhead of creating and passing work to threads don't exceed the work you are doing but the most serious flaw in your code is this
st.start();
st.join();
This means you are always waiting for your background threads to finish immediately after starting them. This means only one is ever running.
For benchmarking purposes I would make sure the code is warmed up and ignore the first 2 - 10 seconds depending on the complexity of what you are doing.
It is worth noting that pulling in data into your CPU cache from a long array is likely to be more expensive than matching your where clause. i.e. you are likely to get the best speed up by applying all the filters to a partition of the data. This is how parallelStream() works.
List<UUID> result = store.parallelStream()
.filter(whereClass)
.map(e -> e.getUUID())
.collect(Collections.toList());
This will collect together all the UUID of the entries which match your predicate using all the CPUs on your machine.
Upvotes: 4