并行处理何时克服顺序处理?

qua*_*ebs 6 java parallel-processing

//    parallel processing

    int processors = Runtime.getRuntime().availableProcessors();
    ExecutorService executorService = Executors.newFixedThreadPool(threads);


    final List<String> albumIds2 = new ArrayList<String>();
    long start2 = System.nanoTime();
    for (final HColumn<String, String> column : result.get().getColumns()) {
        Runnable worker = new Runnable() {

            @Override
            public void run() {
                albumIds2.add(column.getName());
            }
        };
        executorService.execute(worker);
    }
    long timeTaken2 = System.nanoTime() - start2;
Run Code Online (Sandbox Code Playgroud)

我有像上面的例子一样的代码,它创建了一个List<String>专辑ID.该列是来自cassandra数据库的切片.我记录要创建的整个专辑列表所用的时间.

我使用增强的for循环完成了同样的操作,如下所示.

        QueryResult<ColumnSlice<String, String>> result =  CassandraDAO.getRowColumns(AlbumIds_CF, customerId);
    long start = System.nanoTime();
    for (HColumn<String, String> column : result.get().getColumns()) {
        albumIds.add(column.getName());
    }
    long timeTaken = System.nanoTime() - start;
Run Code Online (Sandbox Code Playgroud)

我注意到,无论专辑的数量有多大,每个循环总是花费更短的时间来完成.我做错了吗?或者我需要一台具有多个核心的计算机.我对并行计算的整个概念真的很陌生,请原谅我,如果我的问题是愚蠢的.

Jav*_*ier 6

在您的并行示例中,您要为每列提交一个任务.排队任务的开销可能大于并行执行的好处."任务"实际上是一个快速的(将一个元素插入一个数组并返回)会加剧这种情况.实际上,Executor将每个接收到的任务添加到队列中(并且这种添加成本很高).然后,您将N任务添加到队列,每个任务都会向该数组添加一个元素.并发操作仅执行后一部分

如果任务更复杂,您可以以"块"提交工作(例如,如果您有N个元素和P个处理器,则每个块将具有N/P元素或N/P + 1个元素).该策略有助于减少开销.

另请注意,ArrayList未同步,然后并发执行多个任务可能会损坏您的列表.您可以使用并发集合来避免此问题,但第一个观察仍然存在.

  • 您还可以在更一般的背景下提及[Amdahl定律](http://en.wikipedia.org/wiki/Amdahl%27s_law). (2认同)