rogy Advent Calendar 2017 17日目の記事です. 前の記事はもりゅーのV-REPとC/C++で自作ロボットを動かすでした.
「MATLABは遅い」,ほぅ…
MATLABに対する愚痴として有名なのが,「MATLABは計算が遅い」というものです. 曰く,「MATLABはインタプリタ言語だから」とか,「大規模計算向けに作られていない」とか. 実際の話をすると,MATLABはインタプリタ言語ですが最近のバージョン(R2015b〜)ではJITコンパイラを使った最適化が常時走っていますし,並列計算やGPU計算によって大規模な計算も難なくこなせるように作られています.
では,コードが遅いのはなぜなのでしょうか?MATLABの問題なのでしょうか?コードを改善するだけで実行速度を速くできないのでしょうか? 今回はそんな問いに答えていきたいと思います.
この記事の内容の多くはOctaveにも使える話かと思いますので,フリーソフトウェア狂のOctaveユーザの方も参考にしてみてください.
また,大抵のテクニックは公式のドキュメンテーション[1]にも書いてありますが,この記事ではさらに掘り下げてマニアックな方法についても説明していきます.
なぜ遅いのか
なぜ手元のコードが遅いのか. それには大きく分けて以下の3つが考えられます.
- 反復回数の多いforループを多用している
- 配列の大きさを頻繁に変更している
- アルゴリズムが悪い
1. 反復回数の多いforループを多用している
MATLABにはループ処理が遅いという欠点があります. したがって,反復回数の多いforループをなるべく削減することが高速化への第一歩になります[2].
2. 配列の大きさを頻繁に変更している
MATLABの配列(行列やベクトル)は,動的にメモリを確保できるように作られています. したがって,たとえば
というように,配列の大きさも動的に変更することができます.
しかし,これには変数にメモリを新たに割り当て直す処理が必要となるので,通常の演算に比べて時間がかかります. 2, 3回なら問題ありませんが,これを1000回,1万回と繰り返してしまうと,全体としてパフォーマンスが低下してしまいます.
これを解消するために,zeros
や ones
等のコマンドを使用して,予め必要なサイズのメモリを確保しておくことが推奨されています[3].
3. アルゴリズムが悪い
計算の遅いアルゴリズムを使用してしまうと,実行時間は長くなります(#それはそう). これはMATLAB側ではどうしようもありませんが,MATLABに予め実装されている高速なアルゴリズムを使って,自作の遅いアルゴリズムを置き換えることができる場合があります.
それではどのようにすればこれらの問題を解決できるのか,具体的な例を使って見ていきましょう. また,これらの問題を解決した上でさらに高速化するにはどのようなテクニックが有効かについても解説します.