<div dir="ltr">It seems to me that BlockBuffering is the fastest. I checked and the default buffering mode for stdout is BlockBuffering Nothing. So I went to the C program and checked the value of BUFSIZ which was <span style="color:rgb(0,0,0);line-height:normal">8192. Then I set the buffering mode for stdout to BlockBuffering (Just </span><span style="color:rgb(0,0,0);line-height:normal">8192) so they should be buffering the same, right?</span><div><span style="color:rgb(0,0,0);line-height:normal">It didn't really change the performance at all. Is there something else going on with the buffering I'm not changing?</span></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, May 4, 2016 at 9:45 PM Mike Izbicki <<a href="mailto:mike@izbicki.me">mike@izbicki.me</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That convinces me that your Haskell program is actually slower. My<br>
guess is this is due to a buffering issue, and not due to anything<br>
haskell related. Buffering is how the opeating system makes a<br>
tradeoff between performance and safety for io operations, and I'm<br>
guessing your two code fragments are (behind the scenes) making a<br>
different decision about how to do buffering.<br>
<br>
For a Haskell-related discussion about buffering, see:<br>
<a href="http://book.realworldhaskell.org/read/io.html#io.buffering" rel="noreferrer" target="_blank">http://book.realworldhaskell.org/read/io.html#io.buffering</a><br>
<br>
BTW, a good rule of thumb for io performance in any language is to<br>
never write anything character by character, and instead write large<br>
chunks of characters at once. The above link should make clear why<br>
this is the case.<br>
<br>
On Wed, May 4, 2016 at 6:22 PM, Jake <<a href="mailto:jake.waksbaum@gmail.com" target="_blank">jake.waksbaum@gmail.com</a>> wrote:<br>
> Thanks for the tip! I tried it again, this time using 100000000, and the<br>
> Haskell one runs at around 25 seconds. The C one is only 1.5 seconds. Can<br>
> that still be the run time system?<br>
><br>
> On Wed, May 4, 2016 at 9:18 PM Mike Izbicki <<a href="mailto:mike@izbicki.me" target="_blank">mike@izbicki.me</a>> wrote:<br>
>><br>
>> You need to be doing tests that take much longer to accurately compare<br>
>> runtimes of executables. Here's why:<br>
>><br>
>> Haskell programs have a more complicated run time system than C<br>
>> programs, and the binaries output by GHC are much larger. Therefore,<br>
>> there will be a small additional overhead that you have to pay once<br>
>> when the program starts. For some machines, this could possibly be on<br>
>> the order of 0.3 seconds.<br>
>><br>
>> I'd recommend you scale your test so that it takes at least 30 seconds<br>
>> for the slowest program. This will give you more meaningful results.<br>
>><br>
>> On Wed, May 4, 2016 at 6:07 PM, Jake <<a href="mailto:jake.waksbaum@gmail.com" target="_blank">jake.waksbaum@gmail.com</a>> wrote:<br>
>> > I also tried the more standard forM_ [0..100000] idiom and got similar<br>
>> > times. I hoped loop might be faster, but apparently not.<br>
>> ><br>
>> > On Wed, May 4, 2016 at 9:05 PM Jake <<a href="mailto:jake.waksbaum@gmail.com" target="_blank">jake.waksbaum@gmail.com</a>> wrote:<br>
>> >><br>
>> >> I'm trying to write a program in Haskell that writes a large file at<br>
>> >> the<br>
>> >> end, and it seems like that output alone is taking way longer than it<br>
>> >> should. I don't understand why Haskell shouldn't be able to write data<br>
>> >> as<br>
>> >> quickly as C, so I wrote two test files:<br>
>> >><br>
>> >> -- Test.hs<br>
>> >> import Control.Loop<br>
>> >> import Data.ByteString.Builder<br>
>> >> import System.IO<br>
>> >><br>
>> >> main :: IO ()<br>
>> >> main =<br>
>> >> numLoop 0 1000000 $ \_ -><br>
>> >> hPutBuilder stdout $ char7 ' '<br>
>> >><br>
>> >> // test.c<br>
>> >> #include <stdio.h><br>
>> >><br>
>> >> int main() {<br>
>> >> int i;<br>
>> >> for (i = 0; i < 1000000; i++) {<br>
>> >> fprintf(stdout, " ");<br>
>> >> }<br>
>> >> return 0;<br>
>> >> }<br>
>> >><br>
>> >> I compiled them both with -O2, and ran them redirecting their outputs<br>
>> >> to<br>
>> >> /dev/null. For the Haskell version I got times aroudn 0.3 seconds,<br>
>> >> while the<br>
>> >> C version was around 0.03. Is there any reason why in simple IO the<br>
>> >> Haskell<br>
>> >> version would be slower by an order of magnitude?<br>
>> ><br>
>> ><br>
>> > _______________________________________________<br>
>> > Haskell-Cafe mailing list<br>
>> > <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
>> > <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
>> ><br>
</blockquote></div>