シリアルモニタのパフォーマンス改善を考える

No Image

時々C#で自分の作りたいものを作っては自己満足に浸っています。
シリアルモニタはその中の1つですが、どうしてもデータが膨大になってくると動作が重くなっていきます。
それを解消しようと試行錯誤している奮闘の記録です。

スポンサーリンク

シリアルモニタは実はだいぶ前から地道に作っています。

起動画面
作った当初は軽い動作(1秒に1回くらいの描写)しか考えていなかったものですから、全く問題がなかったのです。
ただ、色々と試しているうちに「10ms毎のデータ受信でも問題くらいの描写にできたらな」と考えるようになりました。
それが地獄につながっているとも知らずに...

文字列の連結

試しに当時にプログラムで10ms毎のデータを送ってみたら1000行くらいで重すぎて使い物になりませんでした。
それはTextBoxの文字列連結に"+="を使っていたからです。
もっと早い方法はないのかと調べてみると、結構出てきます。

とりえあず加算代入はやめてStringBuilderやAppendTextを使うようにしました。
これが結構効果的なようでだいぶパフォーマンスは改善しました。

現在日時の取得(DateTime.Now)

これで大丈夫だろうと思ったら、3000行を超えたあたりからタイムスタンプを表示した場合に重くなったり表示がおかしくなってしまいました。
どうやらタイムスタンプの挿入も改善したほうが良さそうということが分かりました。

スポンサーリンク

データを取得したときにDateTime.Nowを実行して日時を取得しているのですが、このDateTime.Nowが結構重い処理のようです。

DateTime.UtcNowの方が処理が速いのでそれを利用したコードのようです。
下記コードのほうがDateTime.Nowより数十倍は速いようです。

public static class FastDateTime {
    public static TimeSpan LocalUtcOffset { get; private set; }

    public static DateTime Now {
        get { return DateTime.UtcNow + LocalUtcOffset; }
    }

    static FastDateTime() {
        LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
    }
}

よく思いつくなぁ...と感心しつつコピペして使ってみるとちょっと軽くなったかな?という感じではありますが、こういうのはチリツモですからね。

まだまだ重い

これで大丈夫だ!と思っていたのですが、1000行を超えてくるとどうしても重くなってしまいます。
どうやらUIの描写に負担がかかっているのですが、UIの更新頻度を下げるくらいしか今の所しようがありません。
更新頻度を下げるとリアルタイム性というか滑らかさが失われるのでなんか嫌なんですよね。

Arduino IDE に入っているシリアルモニタはシンプルでものすごく軽快です。
ここまでどうやって軽くするかを今もなお考え中です。

シリアルモニタのパフォーマンス改善を考える

スポンサーリンク

Leave a Comment