今日もPythonでプロトタイピングして、そのアルゴリズムがうまくいくことを確かめました。
- アイディアをPythonで書いてみる。
- 結果をグラフ化して、1枚のfigureの中でうまくいっていることが分かるようにする。(Spyder統合環境)
- 複数のデータセットで、うまくいくことを確かめる。
- 別のデータセットでもうまくいくことを確かめる。
- pylint で書き方を標準化する。
- 関数にドキュメンテーションコメントを書く。
- アルゴリズムの根幹の部分と、グラフ作成などの補助機能との区別を意識する。
- アルゴリズムの根幹の部分を別モジュールにする。
- 必要があれば、クラスを作成する。
- pythonでの設計・実装・ドキュメンテーションコメント・実行結果の確認を完了する。
- C++で実装する必要がある部分を明確化する。
- C++で実装する部分を、python実装を参照にして開発に着手する。
- pythonの中で用いたモジュールのC++があれば、それを使って書く(例cv2.imread() → cv::imread())。
- べた書きでもいいから動くようにする。
- あるべき実装、モジュール化(もしくはクラス化)をする。
- それをコマンドラインアプリケーションとして実装したうえで、複数の条件でテストする。
- 可能な引数にconst 修飾子をつける。データメンバーのprivate化、namespaceの利用などをする。
- Doxygenで利用するためのドキュメンテーションコメントを書く。
- モジュールとして組み込むためのライブラリのソースコード、ヘッダファイル、stand-alone用の実行ファイル用のmain関数のソースコードに分離する。
- 公開する必要のない関数は無名名前空間の中に閉じ込める。
- メソッド名、関数名、引数の変数名は、それ自体がドキュメントになるような分かりやすい名前になっているか見直して、必要に応じて名前を変更する。
- 目的の使い方に適した単体テストを書く。
- その単体テストに対して、テストをパスするまでモジュールを改良する。
- 単体テストは正常系だけの記述ではなく、異常系の記述もする。
- テスト完了後のモジュールを、目的のプログラムに組み込む。
このようなやり方で、C++だけで開発するよりは、有効性を早めに検証してから開発をすることができます。
付記:
処理を高速化しようとする場合には
- スクリプトのバージョン管理をする。
- 改版のたびに回帰テストをして、計算結果が劣化していないことを確認する。
- 劣化を生じていないことを確認できる十分な数のテストサンプルを用意してテストする。
- Pythonモジュールのまま処理時間を計測する。
- 計算の中で明示的に2重ループを書くことはしない。適切な関数を使う。
- なぜその処理をしているのか、処理の妥当性のヒントになるコメントを書いて、アルゴリズムをチェックする。
- 演算の順序を入れ替えることで簡略化できる部分を見つけて簡略化する。
- 計算の無駄を減らす。
- 計算の無駄を減らしたときに、処理時間が短くなっていることを確認する。
- 分かりやすい意味のまとまりを意識して、スクリプトを読み直す。
これらを意識しています。