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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe