6
//    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;

上記の例のような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;

アルバムの数がどれほど多くても、for each ループが完了するまでの時間が常に短いことに注意してください。私はそれを間違っていますか?または、複数のコアを備えたコンピューターが必要ですか。私は並列コンピューティングの概念全体に本当に慣れていないので、私の質問がばかげている場合はご容赦ください。

4

2 に答える 2

6

並列の例では、列ごとに 1 つのタスクを送信しています。タスクをキューに入れることのオーバーヘッドは、おそらく並列実行の利点よりも大きくなります。これは、「タスク」が実際に高速である (単一の要素を配列に挿入して返す) ことによって悪化します。実際、 はExecutor受信した各タスクをキューに追加します (追加にはコストがかかります)。次に、N 個のタスクをキューに追加すると、各タスクが要素を配列に追加します。並行操作は後半部分のみを実行します

タスクがより複雑な場合は、作業を「チャンク」で送信できます (たとえば、N 個の要素と P 個のプロセッサがある場合、各チャンクには N/P 個の要素または N/P+1 個の要素が含まれます)。この戦略は、オーバーヘッドの削減に役立ちます。

同期されていないことにも注意してArrayListください。複数のタスクを同時に実行すると、リストが破損する可能性があります。この問題を回避するために同時収集を使用できますが、最初の観察が残ります。

于 2013-03-17T08:34:35.480 に答える
-1

スレッドを作成するために消費される時間と CPU は、スレッドが行っていることよりもはるかに多くなります:albumIds2.add(column.getName());

于 2013-03-17T08:37:43.470 に答える