前回に引き続いて,今度は文字列の操作.一行72文字のファイルを読み込ませ,aの文字数を数える,というのと,aが4回以上現れる行数を数える,というのを書いてみた.ByteString の場合には,B.fold* を使うことになるようだ.今回は,ByteString.Char8 と ByteString.Lazy.Char8 も比較した.
結果. 文字数を数える:
10万行 | 100万行 | 200万行 | 500万行 | |
[Char] | 0.19 | 0.39 | 2.7 | 6.7 |
ByteString.Char8 | 0.08 | 0.08 | 0.46 | 1.12 |
ByteString.Lazy.Char8 | 0.07 | 0.08 | 0.29 | 0.63 |
結果. 行数を数える:
10万行 | 100万行 | 200万行 | 500万行 | |
[Char] | 1.38 | 3.38 | 6.7 | 17 |
ByteString.Char8 | 0.27 | 0.33 | 0.60 | 1.38 |
ByteString.Lazy.Char8 | 0.20 | 0.28 | 0.50 | 1.15 |
測定対象プログラム
import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as BL import Data.List import System.Environment type TpFold s a = ((a -> Char -> a) -> a -> s -> a) opFunc :: Int -> Char -> Int opFunc acc c = if c == 'a' then acc + 1 else acc testFn1 :: TpFold s Int -> s -> Int testFn1 fold = fold opFunc 0 testFn2 :: TpFold s Int -> [s] -> Int testFn2 fold = sum . map (\s -> if fold opFunc 0 s >= 4 then 1 else 0) main :: IO () main = do [arg] <- getArgs case read arg of 1 -> print . testFn1 foldl' =<< getContents 2 -> print . testFn1 B.foldl' =<< B.getContents 3 -> print . testFn1 BL.foldl =<< BL.getContents 4 -> print . testFn2 foldl' . lines =<< getContents 5 -> print . testFn2 B.foldl' . B.lines =<< B.getContents 6 -> print . testFn2 BL.foldl' . BL.lines =<< BL.getContents _ -> error "unknown option"
keyword: haskell performance