2017-08-10 11 views
0

私は大規模なデータセットを処理し、Parallel.ForEachのレコードを処理し、その結果をConcurrentQueue<List<string>>に格納しています。レコードが処理され、レコードの各フィールドは文字列になり、その後Listに追加されます。レコードの末尾にListがある場合は、Enqueuedであり、さらに処理されたすべてのレコードを保持しているConcurrentQueueで処理が行われます。大規模な不確定データセットのスケーラブルなコレクション

セットを処理してから、私のCPU使用量が新しい波からかなり高くなっていることがわかりました。レコードグループを処理する時間が増え始めました。

ここで私の前提は、Listの容量が満たされてから、新しい大きなListにコピーされるということです。この容量に追いつくために必要なCPUのサイズが大きくなるにつれて、初期化サイクルが長くなります。私が扱っているデータセットは不確定なサイズで、各レコードにはさまざまな数の子レコードがあります。親レコードの数は通常500kの領域にあります。

私の最初の考えは、Listを親レコードのCountに初期化することです。 Listはまだ子レコードのために成長する必要がありますが、少なくともそれ以上の時間は成長する必要があります。しかし、より良いスケールのListには、いくつかのコレクションがありますか?あるいは、私の最初の本能とは違うアプローチが良いでしょうか?

答えて

1

ConcurrentQueueはリンクリストとして実装されており、通常のキューとは異なり容量のためにサイズを変更する必要はありません。 あなたの問題は他の場所にあります。

処理されたリストのクリーンアップによって使用されたメモリの量とガベージコレクションの割合を調べるとよいでしょう。

その他のヒント:

  • フィールドから文字列を構築する場合、文字列操作の多くがある場合(すでにこれを行っていない場合)、StringBuilderのを使用しています。
  • レコードに多数のフィールドがあり、事前に知る方法がある場合:リストの代わりにレコードごとに配列を使用するか、リスト容量をレコードのすべての文字列に対応する値に設定します。
+0

ConcurrentQueueを知っておくとよいでしょう。私は文字列そのものについてヒントを調べます(これはコードベースで、今は苦労しています)。フィールド数はレコード間で静的なので、リストの容量の設定は間違いなく可能です。 – bcwiniger

+2

その場合は、リストの代わりにレコードごとに配列を使用します(少し速くなります) –

関連する問題