[Haskell-cafe] Is Haskell IO inherently slower than C?

Duncan Coutts duncan.coutts at googlemail.com
Thu May 5 02:14:57 UTC 2016


On Thu, 2016-05-05 at 01:05 +0000, Jake wrote:
> I'm trying to write a program in Haskell that writes a large file at
> the
> end, and it seems like that output alone is taking way longer than it
> should. I don't understand why Haskell shouldn't be able to write
> data as
> quickly as C, so I wrote two test files:
> 
> -- Test.hs
> import Control.Loop
> import Data.ByteString.Builder
> import System.IO
> 
> main :: IO ()
> main =
>   numLoop 0 1000000 $ \_ ->
>     hPutBuilder stdout $ char7 ' '

This is a highly pessimal use of bytestring builder. You're setting up
a new output buffer for every char. You should either write chars to
the handle buffer, or write one big builder to the handle.

That is either:

numLoop 0 1000000 $ \_ ->
  hPutChar stdout ' '

or

hPutBuilder stdout (mconcat (replicate 1000000 (char7 ' ')))

This isn't the fastest way to use the  bytestring builder, but it's
pretty convenient. The first way isn't great as it has to take the
Handle lock for every char.

On my system those three versions run in time ranges of:
  Hs putChar: 0.154s -- 0.167s
  Hs builder: 0.008s -- 0.014s
  C:          0.012s -- 0.023s

So the answer is no. So long as you can blat bytes into a buffer
quickly enough then there's no reason Haskell IO need be slower than
C.

In terms of benchmarking fairness, neither of these examples (the
builder nor the C version) are the fastest possible ways of blatting
bytes into buffers, though they're both reasonably convenient methods
in both languages.

Duncan


More information about the Haskell-Cafe mailing list