ScottPlot

【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);
        }
    }

最後に

Chartの仕様にあまり詳しくないのですが、簡易計測として計測してみました。
参考になればうれしいです。

応援・要望お待ちしてます

ブログを見ていて「この辺を詳しく知りたい」「このライブラリの使い方を知りたい」「こんなことで困ってる」...etc があれば、コメント・問い合わせ・Twitterで教えてください。質問・ご要望に合わせて解説記事を作ります。

ブログを気に入っていただけたり、「応援してもいいよ」という方がいたら、ブログやSNSでの紹介をお願いします。 あたたかい応援は、中の人の更新の大きな励みになります。

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

COMMENT

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