C vs Python vs Ruby vs Haskell(無意味な処理deベンチマーク)のコードをHaskell でなるべくC実装に忠実に書いて、オーバーヘッドを見てみた。
{-# LANGUAGE ScopedTypeVariables #-} import Control.Monad import Data.Array.IO import Data.IORef reverseI :: IOUArray Int Int -> IO () reverseI arr = do (start, end) <- getBounds arr let size = end - start + 1 let list = range (start, start + size `div` 2) forM_ list $ \i -> do let j = end + start - i itemI <- readArray arr i itemJ <- readArray arr j writeArray arr j itemI writeArray arr i itemJ size :: Int size = 4000 main :: IO () main = do counter <- newIORef 1 arr :: IOArray Int (IOUArray Int Int) <- newArray (0, size - 1) undefined bounds <- getBounds arr forM_ (range bounds) $ \i -> do arr' :: IOUArray Int Int <- newArray (0, size - 1) 0 writeArray arr i arr' bounds' <- getBounds arr' flip mapM_ (range bounds') $ \i' -> do current <- readIORef counter writeArray arr' i' current writeIORef counter $ current + 1 forM_ (range bounds) $ \i -> do arr' <- readArray arr i reverseI arr' arr' <- readArray arr (snd bounds) bounds' <- getBounds arr' n <- readArray arr' (snd bounds') putStrLn $ show n
始め IOArray を使ってたら実行が終わらないレベルだったけど、IOUArray にしたらなんとかなった。
% time ./hogehoge_c 15996001 ./hogehoge_c 0.04s user 0.03s system 97% cpu 0.071 total % time ./hogehoge_hs 15996001 ./hogehoge 0.28s user 0.04s system 96% cpu 0.325 total
普通のLL系よりはさすがに速いものの、もうちょっとがんばりたいなーと思った。これ以上攻めるならForeignモジュールとか使えばいいのかな。