.NETのChartクラス(コントロール)と、ScottPlotの表示速度の比較してみました。
「ScottPlotってどれくらい早いの?」という方の参考になればうれしいです。
- ScottPlotとChartクラスの(再)描画速度の比較結果
- 計測時のコード
比較結果
比較結果は以下の通りです。
ScottPlotのほうが約2倍ぐらい早い結果になりました。
ゼロからの描画速度を比較する予定でしたが、Chartクラスの描画が非同期であったため計測が難しく、一度グラフを表示した後の再描画を計測してみました。
ゼロからの描画については再度挑戦してみたいと思います。
対象 | 平均描画時間 |
ScottPlott | 791.7 [msec] |
Chart | 1346.0 [msec] |
古いノートPCで計測しているため、最新スペックのPCであればもっと双方の表示時間は早くなると思います。あくまで、同環境でのChartとScottPlotの差としてお考えください。
計測環境と方法
環境と計測方法は以下の通りです。
計測方法
ScottPlotとChartクラスで、10万ポイントの散布図を再表示する時間を計測しています。
100回計測し、平均値を算出しています。
計測環境
機器 | 型式 | スペック |
CPU | Core i5 3427U | 1.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);
}
}
最後に
簡易計測として測ってみました。参考になればうれしいです。
伝わるグラフを作る
この記事の読者の方々は、少しでも「分かりやすく」「見やすく」といったことも考えてアプリケーションを作られている方が多いと思います。それだけでも十分に素晴らしいですが、「そもそもどんなグラフがユーザーにとって分かりやすいか?」といった、デザインやUXの知識・視点も結構おもしろいです。
以下の本など、比較的手軽な値段で読める書籍がいくつかあるので、ぜひ覗いてみてください。
応援・要望お待ちしてます
ブログを見ていて「この辺を詳しく知りたい」「このライブラリの使い方を知りたい」「こんなことで困ってる」...etc があれば、コメント・問い合わせ・Twitterで教えてください。質問・ご要望に合わせて解説記事を作ります。
ブログを気に入っていただけたり、「応援してもいいよ」という方がいたら、ブログやSNSでの紹介をお願いします。 あたたかい応援は、中の人の更新の大きな励みになります。