C#でParallel

RecordedValues()使って、タグの情報を取得するコードを書いてます。

1000タグで、それぞれのタグにはだいたい4000のタイムスタンプと値があります。

だいたい12 -18秒くらいかかりました。このデータ量で12-18秒は一般的と言えるのでしょうか?

さらに処理時間を短くするのにParallel処理を入れてみましたが、処理時間は変わりませんでした。

下記のようなコードにして試してみました。

この場合、Parallel処理はできないのでしょうか?

また、他に処理時間を短縮できる方法がありますか?

 

IEnumerable<AFValues> res = pointList.RecordedValues(range, AFBoundaryType.Inside, "", true, config);

Parallel.ForEach(res,  pointResults =>

{

      pointResults.GetValueArrays(out values, out timestamp, out flags);

});

Parents
  • 確認ですが、PI Data Archiveとコードは同じマシンで実行していますでしょうか。

    12-18秒と言いましたが、RecordedValuesの関数だけは何秒ぐらい掛かりますでしょうか。

  • PI Data Archiveとコードは別のマシンになります。

    また、RecordedValues()の時間はほどんどかかっていません。すぐに返ってきます。

    そのあとのForEachのループで10秒とかかかってしまいます。

  • ありがとうございます。

     

    このループで際にParalell処理をいれて、処理時間を短くすることはできないのでしょうか?

    (Parallelありのコードとなしのコードで試しましたが、処理時間は変わりませんでした。)

  • 私の環境で再現し、同じぐらいの時間が掛かりました。

    GetValuesArrayの関数はただ、AFValuesを使いループしているだけなので、

    別の呼び方で早く処理ではないと考えられます。

     

    パフォーマンスが悪い場合は、生データの代わりに内挿値を取得するとイベントの数を減ることができます。

  • 明確にするために、GetValuesArray似ている関数を作成しました。

    結果は、Parallelの実行する時間とForEachのは同じぐらい掛かります。

     

            public static void GetValueArrays(AFValues afvalues, out object[] values, out AFTime[] timestamps)

            {

                int count = afvalues.Count();

                values = new object[count];

                timestamps = new AFTime[count];

                for (int i = 0; i < count; i++)

                {

                    values = afvalues.Value;

                    timestamps = afvalues.Timestamp;

                }

                return;

            }

     

    Parallelについて詳しくないですがスレッドの管理するだけに時間が掛かります。

    タグ毎に10msぐらい時間が掛かります。もし、スレッドの管理する時間は何msだとしたら、パフォーマンスがあまり変わらないと考えられます。

  • そのほか、以下ユーザーカンファレンスのビデオもパフォーマンス向上の参考になります。

    Best Practices for Building AF SDK applicationのビデオのご紹介(ユーザーカンファレンス2017)

    まずはRPC Metricsを見てみるのが良いかと思います。

Reply Children
No Data