
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