[Haskell-cafe] More fun with micro-benchmarks and optimizations.
(GHC vs Perl)
Don Stewart
dons at galois.com
Wed Jul 23 17:00:12 EDT 2008
brad.larsen:
> And against gawk 3.1.5:
>
> $ time awk -F: '{sum += 1 / $2} END{print sum}' test.out
> 3155.63
>
> real 0m0.197s
> user 0m0.184s
> sys 0m0.004s
>
> compared to Don's Haskell version:
>
> $ time ./fastSum < test.out
> 3155.626666664377
>
> real 0m0.072s
> user 0m0.056s
> sys 0m0.004s
>
> compared to the Corey's perl version:
>
> $ time perl Sum.pl
> Duration (sec): 3155.62666666438
>
> real 0m0.181s
> user 0m0.164s
> sys 0m0.012s
>
Another variant, using a non-copying readDouble (available in
bytestring-lexing package 0.1.2),
{-# OPTIONS -fbang-patterns #-}
import qualified Data.ByteString.Char8 as S
import qualified Data.ByteString.Unsafe as S
import Data.ByteString.Lex.Double
main = print . go 0 =<< S.getContents
where
go :: Double -> S.ByteString -> Double
go !n !s = case unsafeReadDouble s' of
Nothing -> n
Just (k,t) -> let delta = 1 / k in go (n+delta) t
where
s' = case S.elemIndex ':' s of
Nothing -> S.empty
Just i -> S.unsafeDrop (i+2) s
Computes in:
$ time ./Fast < test.out
3155.626666664377
./Fast < test.out 0.02s user 0.00s system 80% cpu 0.025 total
So that's probably a good place to stop.
Note the general rules:
* strict bytestrings
* tight tail-recursive loops with strict, atomic accumulators
* non-copying parsing.
-- Don
More information about the Haskell-Cafe
mailing list