1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C# PLINQのスレッド周りについて

Posted at

経緯

PLINQについて速いと噂には聞いていたがなぜ速いのかというところに疑問を
感じ、どんな動きをしているかを簡単に共有できればなと感じて

そもそもPLINQって?

ドキュメントには下記のように記載されています。

データ ソースをセグメントにパーティション分割し、複数のプロセッサで個々のワーカー スレッドの各セグメントに対してクエリを並行実行します。

うーん、並行実行というのはマルチスレッドのことなのかな?
マルチスレッド自体複雑だからな、、、 async/awaitとかもなんだかんだ理解まで時間かかったし、、、

実際にやってみた

前置きが長くなりましたが、実際に今までForeachで処理していた部分をAsPararell().ForAll()を使用して、どのくらい変化が現れるかを実験してみました。
また、実際にプログラムを作成する上で下記記事を参考にさせていただきました、本当にありがとうございます。
(参考記事:PLINQの実行速度と高速な書き方)

Program.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Start");
        var app = new Program();
        app.Run();
        Console.WriteLine("End");
    }

    public void Run()
    {
        const int N = 500;
        var list = Enumerable.Range(1, N).ToList();

        var sw = new System.Diagnostics.Stopwatch();

        // for
        sw.Restart();
        list.ForEach(x => Thread.Sleep(1));
        Console.WriteLine("for      : " + sw.Elapsed);

        // PLINQ
        sw.Restart();
        list.AsParallel().ForAll(x => Thread.Sleep(1));
        Console.WriteLine("PLINQ     : " + sw.Elapsed);
    }
}

結果がこちらとなります。

$ dotnet run
Start
for      : 00:00:00.9243632
PLINQ     : 00:00:00.1569520
End

確かに早いですよね。

ここからが本題でこいつがどんな感じで動いているのかを調べてみました。
端的に言うと、マルチスレッドになっているのかどうかとかその辺を見てみました(これだけ早ければマルチスレッドで動いていることはほぼ間違いないのですが・・・)

Program.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Start");
        var app = new Program();
        app.Run();
        Console.WriteLine("End");
    }

    public void Run()
    {
        // アウトプットが多いので10に変更
        const int N = 10;
        var list = Enumerable.Range(1, N).ToList();

        // for
        list.ForEach(x =>
        {
            Console.WriteLine("ForEach Start Theread:" + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1);
            Console.WriteLine("ForEach End Theread:" + Thread.CurrentThread.ManagedThreadId);
        });

        // PLINQ
        list.AsParallel().ForAll(x => 
        {
            Console.WriteLine("PLINQ Start Theread:" + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1);
            Console.WriteLine("PLINQ End Theread:" + Thread.CurrentThread.ManagedThreadId);
        });
    }
}

結果がこちらです。

$ dotnet run
Start
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
ForEach Start Theread:1
ForEach End Theread:1
PLINQ Start Theread:1
PLINQ Start Theread:5
PLINQ Start Theread:10
PLINQ Start Theread:7
PLINQ Start Theread:4
PLINQ Start Theread:9
PLINQ Start Theread:6
PLINQ Start Theread:8
PLINQ End Theread:6
PLINQ End Theread:10
PLINQ End Theread:4
PLINQ End Theread:9
PLINQ End Theread:1
PLINQ End Theread:7
PLINQ End Theread:5
PLINQ Start Theread:5
PLINQ End Theread:8
PLINQ Start Theread:6
PLINQ End Theread:6
PLINQ End Theread:5
End

見れば一目瞭然ですが、純粋なForEachの場合にはメインスレッドを使用しているのに対して、PLINQの場合にはマルチスレッドで動いており処理が完了し開放されたスレッドを再び利用するため処理の無駄を省き大幅にパフォーマンスが改善されるのですね。

よかったら参考にしてみてください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?