我编写了一个简单的 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())
);
}
}
}
最佳答案
您必须小心,创建工作并将其传递给线程的开销不要超过您正在执行的工作,但代码中最严重的缺陷是这个
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。
关于Java并发比连续慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40072625/