Relative speed comparison below Udo Stenzel wrote: > Sebastian Sylvan wrote: > >>On 1/5/06, Chris Kuklewicz <[EMAIL PROTECTED]> wrote: >> >>>There is no need to beat a dead horse, though. This benchmark sets out >>>to test fgets / atoi, and that is all. There are better benchmarks to >>>spend time on. >> >>I agree. The benchmark really is about how fast you can call low-level >>IO system calls. But since Haskell is a high-level language it's >>natural that it's a bit difficult to get access to these unsafe (but >>fast) low-level functions. > > > There's probably a bit more to it. First off, one could legitimately > argue that (liftM lines getContents) is the Haskell way to do line > oriented IO. The real question is, why does the fast solution have to > be ugly > > >>foreign import ccall "stdio.h" fgets :: CString -> Int -> Ptr CFile ->IO >>CString >>foreign import ccall safe "stdlib.h" atoi :: CString -> Int >>foreign import ccall safe "stdio.h &(*stdin)" c_stdin :: Ptr CFile > > > and why does the idiomatic solution have to be slow? > > | main = print . sum . map read . lines =<< getContents > > The biggest hit is probably the construction of a huge String as linked > list, which cannot be deforested away (not with the foldr/build > mechanism anyway). Assuming we find a better representation for > Strings, we could make some headway here and in many other benchmarks. > > So I think, just by replacing String and along with it getContents, > lines and read, we will get competitive speed and retain the ability to > handle arbitrarily long lines. Of course, the shootout wouldn't care > for a feature that is otherwise quite important in practice... Anyway, > I'll try try to come up with something and then follow up on this. > > > Udo.
The solution on the wiki (Char by Char) is the fastest I could make : > print . total =<< getContents Time was 1.00 seconds I tried using getLine and it was slower: > let next rt = do line <- catch getLine (\_ -> return []) > if (null line) then return (I# rt) > else next (rt +# aLine line) Time was 3.79 seconds I tried using getContents and lines and it was slowest: > total <- return.(next 0#).lines =<< getContents Time was 4.76 seconds >From this, I assume the buffering that getContents does is very optimized. The cost of getLine was very nontrivial. So for non-binary input, I would recommend using getContents and processing it Char by Char. -- Chris _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
