2009年11月7日土曜日

Haskellのプログラムを高速化するための7つの方法


以前のエントリでHaskellのプログラムが遅いというのが不満だったので、Haskell-cafeにメールして聞いてみました。

いくつか高速化するためのテクニックを教えてもらったので、まとめてみます。

-O2オプション


ghcでコンパイルするときに-Oを付けると最適化してコンパイルされますが、それを-O2オプションに変えるとさらに最適化されます。

-fexcess-precision


ghcでコンパイルするときに、-fexcess-precisionオプションを付けてnumber-crunchingをすると、処理が速くなります。
★number-crunchingって何だろう?

-fvia-C,-optc-O3


これらのオプションを付けると、HaskellのコードをいったんCに変換し、それを-O3オプション付きでコンパイルします。2回コンパイルするのでコンパイルにかかる時間は増えますが、さらなる高速化を期待できます。

-fvia-Cと-optc-O3を付けることで、約10%高速化できるようです。

UNPACKプラグマと正格フラグ


データ構造の要素にUNPACKプラグマと正格フラグ(!)を付けることで、計算の高速化を期待できます。

たとえば、Particleの定義を、
data Particle = Particle { pos, vel :: {-# UNPACK #-} !Vector3,
mass, rho, prs :: {-# UNPACK #-} !Scalar }
のようにします。

-fexcess-precisionオプションとUNPACKプラグマ、正格フラグを使うことで、約30%高速化できるようです。

★!フラグを付けることで正格評価されるという理解でいいのかな?
★UNPACKプラグマを付けるとどうなるんだろう?非ボックス化というやつ?抽象化せず直で要素を扱うのかな?

ByteString


HaskellのStringは処理が遅いらしいので、代わりにByteStringを使うことで高速化を望めます。

コンパイルオプションの最適化


Haskellに限ったテクニックではありませんが、Acoveaのようなコンパイルオプション最適化ツールを使うことで、コンパイルオプションを最適化して高速化できます。Acoveaは遺伝的アルゴリズムでコンパイルオプションを最適化するようです。

DPH


DPHを使うことでも高速化できるようです。
★DPHってなんだろう?

参考になれば。
-

2 件のコメント:

匿名 さんのコメント...

僕もHaskellを数値計算に使いたいなって思っていたから参考になります。
DPHはData Prallel Haskellっていうものらしいですよ.

kamonama さんのコメント...

コメントありがとうございます!

Haskell-cafeで私のコードを実行していろいろ教えてくれた人によると、HaskellでもC++と遜色ない速さで処理できるようです!
C++: 12.914s
Haskell: 13.393s

DPHはData Prallel Haskellのことだったんですね。並列Haskell。調べてみます!