minus1216
再帰的な型をキーとする要素数の少ないMapに対して頻繁にlookupをかけるコードを書いており、高速化したいです。はじめはHashMapを使おうと思っていたのですが、hashWithSaltをプリミティブな演算のみで実装しても再帰のオーバーヘッドが大きかったのか、かえって遅くなってしまいました
data Expr =
ExprVar Int
| ExprBottom
| Implies Expr Expr
| And Expr Expr
| Or Expr Expr
deriving (Eq, Ord)HashMap よりも containers の Data.Map.Strict.Map の方が軽いかもしれませんねOrd の比較を使うIntMap が使えれば効率よさそうですし(実装までは見てませんがhashWithSalt を末尾再帰で計算してみるってところでしょうか。すでにやっていれば恐縮ですがlcgs i =
(48271 * i) `remInt` 0xffff
hashWithSalt' :: Int -> Expr -> Int
hashWithSalt' salt expr =
case expr of
ExprVar t -> lcgs (salt + t)
ExprBottom -> lcgs salt
Implies e1 e2 -> lcgs (hashWithSalt' salt e1 * 5 + hashWithSalt' salt e2) * 3 + 0
And e1 e2 -> lcgs (hashWithSalt' salt e1 * 5 + hashWithSalt' salt e2) * 3 + 1
Or e1 e2 -> lcgs (hashWithSalt' salt e1 * 5 + hashWithSalt' salt e2) * 3 + 2