我编写了一个简单的java类来对我的数据存储执行部分搜索,但是当我针对连续版本运行时,执行时间较慢。
连续搜索耗时11毫秒 并发搜索需要23毫秒
我从未编写过线程应用程序,我希望这是一个非常简单的操作。有人可以通过此代码片段指出我正确的方向。我不知道是残酷的!
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())
);
}
}
}
答案 0 :(得分:4)
你必须要小心,创建和传递工作到线程的开销不会超过你正在做的工作,但代码中最严重的缺陷就是这个
st.start();
st.join();
这意味着您始终在等待后台线程在启动后立即完成。这意味着只有一个人在运行。
出于基准测试目的,我会确保代码预热,并且忽略前2到10秒,具体取决于您正在执行的操作的复杂程度。
值得注意的是,将数据从长数组中提取到CPU缓存中可能比匹配where子句更昂贵。即,通过将所有过滤器应用于数据分区,您可能会获得最佳加速。这就是parallelStream()的工作原理。
List<UUID> result = store.parallelStream()
.filter(whereClass)
.map(e -> e.getUUID())
.collect(Collections.toList());
这将使用您计算机上的所有CPU收集与谓词匹配的所有条目的UUID。