简体   繁体   English

Java并发比连续慢吗?

[英]Java concurrent is slower than consecutive?

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. 我编写了一个简单的Java类来对数据存储执行部分搜索,但是当我针对连续版本运行它时,执行时间会变慢。

Consecutive Search took 11 milliseconds Concurrent Search took 23 milliseconds 连续搜索花费了11毫秒并行搜索花费了23毫秒

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())
            );
        }
    }

}

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. 为了进行基准测试,我将确保代码已预热,并根据您执行的复杂性忽略了前2到10秒。

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. 值得注意的是,将数据从长数组中提取到CPU缓存中可能比匹配where子句更昂贵。 ie 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. 这就是parallelStream()的工作方式。

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. 这将使用计算机上的所有CPU收集与谓词匹配的所有条目的UUID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM