Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
-- ghc -O --make BenchStringToInt.hs && ./BenchStringToInt --output bench_string_to_int.html&& open bench_string_to_int.html
import Criterion.Main
import Data.Maybe (fromMaybe)
import Text.Parsec (parse)
import Text.Parsec.Token (makeTokenParser, integer)
import Text.Parsec.Language (haskellStyle)
import Data.Char (digitToInt, isDigit)
main = defaultMain [
bgroup "string to int" [ bench "read" $ nf withRead numbers
, bench "parsec" $ nf withParse numbers
, bench "naive" $ nf withDigitToInt numbers
]
]
counts = [1..75000]
numbers = map show $ foldl1 (++) [counts, counts, counts, counts]
withRead :: [String] -> [Int]
withRead xs =
map toInt' xs
where
toInt' s = read s :: Int
withParse :: [String] -> [Int]
withParse xs =
map toInt' xs
where
toInt' = fromInteger . either (const 0) id . parse (integer . makeTokenParser $ haskellStyle) "integer"
withDigitToInt :: [String] -> [Int]
withDigitToInt xs = map (fromMaybe 0 . stringToInt) xs
stringToInt :: String -> Maybe Int
stringToInt xs
| all isDigit xs = Just $ loop 0 xs
| otherwise = Nothing
where
loop acc [] = acc
loop acc xs' = foldl (\acc' x -> acc' * 10 + digitToInt x) acc xs'
benchmarking string to int/read
time 595.9 ms (587.9 ms .. 608.0 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 595.4 ms (592.9 ms .. 597.1 ms)
std dev 2.510 ms (0.0 s .. 2.898 ms)
variance introduced by outliers: 19% (moderately inflated)
benchmarking string to int/parsec
time 433.3 ms (420.9 ms .. 446.4 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 427.9 ms (422.9 ms .. 430.5 ms)
std dev 4.343 ms (0.0 s .. 4.514 ms)
variance introduced by outliers: 19% (moderately inflated)
benchmarking string to int/naive
time 14.43 ms (14.08 ms .. 14.77 ms)
0.997 R² (0.995 R² .. 0.999 R²)
mean 14.29 ms (14.13 ms .. 14.47 ms)
std dev 398.1 μs (335.5 μs .. 493.0 μs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment