1

2 つの単純なループを作成しました。

1 つは、標準の「for」を使用しています。

Stopwatch sw = Stopwatch.StartNew(); 

            for (int i = 0; i < 1000000; i++)
            {
                Console.WriteLine(i);
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
            Console.ReadKey();

2 つ目は、より高速であると思われる Parallel.For を使用することです。

sw.Restart();
            Parallel.For(0,1000000,i =>
                    {
                        Console.WriteLine(i);
                    });              

            sw.Stop();
            Console.WriteLine(sw.Elapsed);

残念ながら、最初の実行には約 53 秒かかり、次の実行には約 1 分 50 秒かかります (!!!)。

それはなぜですか、そして私は何を間違っていますか?

4

3 に答える 3

4

Parallel.Forループを高速化することは想定されていません。反復を並行して実行することになっています。

あなたの試みでは、ループを並列化することによって提供される速度向上に匹敵することができないリソースを使用するコードを使用しました (おそらく、同期が必要なため、十分な帯域幅がないためなど)。したがって、スレッドに追いつくことができないリソースをめぐってスレッドが競合しているだけです。あなたのシナリオは、並列処理を必要としないだけです (少なくとも、あなたが試みている方法ではありません)。

ループのパフォーマンスを向上させる方法を知りたい場合はParallel.For、結果を配列内の排他的な (反復ごとに) インデックスに保存する計算をループ内で行うことを検討し、それらの計算が依存しないようにしてください。何らかの方法で他の反復の結果。

于 2013-05-09T09:04:06.200 に答える
0

コードを linqpad で試してみたところ、for ステートメントを使用して 9 秒、Parallel.For を使用して 12.5 秒かかりました。

データベースやコンソール出力などの I/O リソースにアクセスしようとすると、ロック メカニズムを使用してスレッドを同期する必要があります。とにかく、挿入または選択ステートメントのためにデータベースに並行してアクセスすることはお勧めしません。

ただし、この変更でコードを試してください。

 Stopwatch sw = Stopwatch.StartNew(); 
 StringBuilder str = new StringBuilder();

 for (int i = 0; i < 1000000; i++)
 {
      str.AppendLine(i.ToString());
 }

 sw.Stop();
 Console.WriteLine(sw.Elapsed);

 str = new StringBuilder();
 sw.Restart();

 Parallel.For(0,1000000,i =>
                {
                    str.AppendLine(i.ToString());
                });              

 sw.Stop();
 Console.WriteLine(sw.Elapsed);

これにより、時間が数百ミリ秒に短縮されます。

于 2013-05-09T09:04:24.530 に答える