0

SSD ディスクに多数の小さなファイルを作成する際のパフォーマンスを最適化しようとしています。

ConcurrentBag<string[]> cb = new ConcurrentBag<string[]>();
cb.AsParallel().ForAll(fa => File.WriteAllText(fa[0], fa[1]));

ConcurrentBag<string[]>= 80048の合計数は、cb.Sum(gbc => Encoding.UTF8.GetByteCount( gbc[1] ) );393441217 バイトを返します。

他の場所で を実行するxml.Save();と、〜 750MB のファイルが作成されます。

最初の状況は、完了するまでに 3 分 30 秒かかります。2 番目の 20 秒。

すべての個別の書き込み操作を処理するためのオーバーヘッドがあることは理解していますが、それでも 3 分 30 秒は少し長いようです。私はすでに forall で並列化を試みましたが、これはかなり役に立ちました (それ以前は、完了するまでに 6 ~ 8 分かかりました)。一括ファイル作成のパフォーマンスを最適化するために、コードに他にどのような変更を加えることができますか?

4

2 に答える 2

1

実際、複数の同時 IO 操作は、特に従来のディスクでは速度が大幅に低下する可能性があります。ConcurrentQueue複数のファイルを書き込むために使用することをお勧めします。

StreamWriterまた、書き込み速度を上げるために、バッファ サイズに切り替えて制御することもできます。

    ConcurrentQueue<string[]> concurrentQueue = new ConcurrentQueue<string[]>();

    // populate with some data
    for (int i = 0; i < 5000; i++)
    {
        concurrentQueue.Enqueue(new string[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() });
    }

    while (true)
    {
        string[] currentElement;
        bool success = concurrentQueue.TryDequeue(out currentElement);
        if (success)
        {
            const int BufferSize = 65536;  // change it to your needs
            using (var sw = new StreamWriter(currentElement[0], true, Encoding.UTF8, BufferSize))
            {
                sw.Write(currentElement[1]);
            }
        }
    }
于 2015-08-04T14:31:11.340 に答える
1

また、ForAll の代わりに ForEach を使用するようにしてください。投稿でいくつかの正当な理由を見つけることができますhttp://reedcopsey.com/2010/02/03/parallelism-in-net-part-8-plinqs-forall-method/

投稿ガイドラインは

ForAll 拡張メソッドは、PLINQ 式によって返される並列クエリの結果を処理するためにのみ使用する必要があります。

于 2015-08-04T14:43:40.100 に答える