C# PR

【C#】ScottPlot vs Chart 描画速度の比較

記事内に商品プロモーションを含む場合があります

.NETのChartクラス(コントロール)と、ScottPlotの表示速度の比較してみました。
「ScottPlotってどれくらい早いの?」という方の参考になればうれしいです。

比較結果

比較結果は以下の通りです。
ScottPlotのほうが約2倍ぐらい早い結果になりました。

ゼロからの描画速度を比較する予定でしたが、Chartクラスの描画が非同期であったため計測が難しく、一度グラフを表示した後の再描画を計測してみました。
ゼロからの描画については再度挑戦してみたいと思います。

対象 平均描画時間
ScottPlott 791.7 [msec]
Chart1346.0 [msec]
描画時間の平均値の比較


古いノートPCで計測しているため、最新スペックのPCであればもっと双方の表示時間は早くなると思います。あくまで、同環境でのChartとScottPlotの差としてお考えください。

計測環境と方法

環境と計測方法は以下の通りです。

計測方法

ScottPlotとChartクラスで、10万ポイントの散布図を再表示する時間を計測しています。
100回計測し、平均値を算出しています。

計測環境

機器型式スペック
CPU Core i5 3427U1.8Ghz
メモリ4GB
ストレージSATA SSD

ScottPlot 計測ソースと画面

画面を表示する際に一度グラフを描画し、「計測」ボタンで100回の計測を開始します。

    public partial class Form7 : Form
    {
        // サンプル用のデータを格納するリストです
        List<double> pointX;
        List<double> pointY;

        // 時間計測用のストップウォッチです
        System.Diagnostics.Stopwatch stopWatch;

        // 計測結果を格納するリストです
        List<long> resultList;

        public Form7()
        {
            InitializeComponent();
            //
            // リストなどの初期化をします
            //
            pointX = new List<double>();
            pointY = new List<double>();

            stopWatch  = new System.Diagnostics.Stopwatch();

            // 10万点のポイントデータを作成します
            for (int i = 0; i < 100000; i++)
            {
                pointX.Add(1.0 * i);
                pointY.Add(1.0 * i);
            }

            // 散布図としてデータをセットします
            formsPlot1.plt.PlotScatter(pointX.ToArray(), pointY.ToArray());

            // 一度描画します
            formsPlot1.Render();
        }


        //
        // 計測のボタン用の関数です。
        // 再描画にかかる時間を計測します。
        //        
        private void button1_Click(object sender, EventArgs e)
        {
            // 計測結果格納用のリストです
            resultList = new List<long>();

            // 描画時間を計測します
            for (int cnt = 0; cnt < 100; cnt++)
            {
                stopWatch.Restart();

                formsPlot1.Render();
                
                stopWatch.Stop();
                
                // 経過時間(ミリ秒)を保存します
                resultList.Add(stopWatch.ElapsedMilliseconds);

            }

            // リストから平均値と合計時間を算出して、文字列型に変換します
            string resultAvg = resultList.Average().ToString();
            string resultSum = resultList.Sum().ToString();

            // メッセージボックスで表示します
            MessageBox.Show("agv: " + resultAvg + " sum: " + resultSum);

        }
    }

Chart クラスの計測ソース

同様に、画面を表示する際に一度グラフを描画し、「計測」ボタンで100回の計測を開始します。

using System.Windows.Forms.DataVisualization.Charting; // Chartで使用します。

 public partial class Form5 : Form
 {
        // サンプル用のデータを格納するリストです
        List<double> pointX;
        List<double> pointY;

        // 時間計測用のストップウォッチです
        System.Diagnostics.Stopwatch stopWatch;

        // Chart用のオブジェクトです
        Series series;

        public Form5()
        {
            InitializeComponent();

            //
            // 各種リストなどを初期化します
            //
            pointX = new List<double>();
            pointY = new List<double>();

            stopWatch = new System.Diagnostics.Stopwatch();

            series = new Series();
            series.ChartType = SeriesChartType.Point;

            //
            // 10万点のポイントデータを作成します
            //
            int MAX_COUNT = 100000;
            for (int i = 0; i < MAX_COUNT; i++)
            {
                double data = i * 1.0;
                series.Points.AddXY(data, data);
            }

            // 空のポイントデータがセットされている?
            // ようなのでクリアします。
            chart1.Series.Clear();

            // 一度描画します
            chart1.Series.Add(series);

        }

        //
        // 計測のボタン用の関数です。
        // 再描画にかかる時間を計測します。
        //
        private void button1_Click(object sender, EventArgs e)
        {
            // 計測結果を格納するリストです
            List<long> resultList = new List<long>();

            // 描画時間を計測します
            for (int cnt = 0; cnt < 100; cnt++)
            {
                stopWatch.Restart();

                // 再描画を実行します
                chart1.Series.Invalidate();

                // 明示的に画面を更新します。
                // これがないと画面が非同期に更新されるようです。
                // 計測結果が0秒になってしまいます。
                chart1.Update();

                stopWatch.Stop();

                // 計測結果を保存します
                resultList.Add(stopWatch.ElapsedMilliseconds);

            }

            // リストから平均値と合計時間を算出して、文字列型に変換します
            string resultAvg = resultList.Average().ToString();
            string resultSum = resultList.Sum().ToString();

            // メッセージボックスで計測結果を表示します
            MessageBox.Show("agv: " + resultAvg + " sum: " + resultSum);
        }
    }

最後に

簡易計測として測ってみました。参考になればうれしいです。

自分でコードを打つ時間がない時は

『自分でやるには時間がない、でも頼める人もいない』と悩んでいるあなたに「ココナラ」があります。

登録者数は約200万。専門家・フリーランスも多く、制作サンプルやレビューを見て自分にあった人を選ぶことができます。特に人気の「Python」なら絶対数が多いので「デキる人」も見つけやすいです。登録は無料なのでどんな人・チームがいるか確認してみてください。

(HP製作・動画製作・面倒な業務文書の作成代行も依頼もできますよ)

1分以内に完了!無料会員登録はこちら

お知らせ

今月号の『Software Design』はドメイン駆動設計(DDD)。実例を交えたDDDの手法の解説が特集されています。

編集:Software Design 編集部
¥1,562 (2024/03/13 12:59時点 | Amazon調べ)

質問・要望 大歓迎です

「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。

使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です