2013-03-17 15 views
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; 

私はアルバムidsのList<String>を作成する上記の例のようなコードを持っています。 カラムは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; 

私は、アルバムの数がどんなに多くても、各ループはいつも完了に時間がかかります。それは間違っていますか?または私は複数のコアを持つコンピュータが必要ですか?私は本当に並列コンピューティングの概念全体に私の質問がばかだと私を許してください新しいです。

+0

"*複数のコアを持つコンピュータが必要ですか?*" =>はい。下記のように、パフォーマンスを向上させるために、少なくとも100以上のバッチで列をグループ化してください。 – assylias

答えて

6

あなたのパラレルの例では、各列に1つのタスクを送信しています。タスクをエンキューするオーバーヘッドはおそらくパラレル実行のメリットよりも大きいでしょう。これは、 "タスク"が本当に速い(配列に単一の要素を挿入して戻る)ことによって悪化します。実際、Executorは、受信した各タスクをキューに追加します(さらに、の追加はコストがかかります)。次に、Nタスクをキューに追加し、各タスクは要素を配列に追加します。同時実行で後半部分のみを実行する

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

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

+0

ポイントは非常に明確かつ正確な答えを指摘した。 – qualebs

+2

もっと一般的な文脈で[Amdahl's law](http://en.wikipedia.org/wiki/Amdahl%27s_law)に言及することもできます。 –

-1

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