4 ms·
Haskell can be even simpler: main = putStr (repeat '1') [Edit: as pointed out below, this is no longer the case!] Strings are printed one character at a
by dllthomas 4y ago
Haskell can be even simpler:
main = putStr (repeat '1')
[Edit: as pointed out below, this is no longer the case!]
Strings are printed one character at a time in Haskell. This choice is justified by unpredictability of the interaction between laziness and buffering; I am uncertain it's the correct choice, but the proper response is to use Text where performance is relevant.
- nequo 4y agoWow, this does 160 MiB/s. That's a huge improvement! The output of strace looks completely different: poll([{fd=1, events=POLLOUT}], 1, 0) = 1 ([{fd=1, revents=POLLOUT}]) write(1, "11111111111111111111111111111111"..., 8192) = 8192 poll([{fd=1, events=POLLOUT}], 1, 0) = 1 ([{fd=1, revents=POLLOUT}]) write(1, "11111111111111111111111111111111"..., 8192) = 8192 With the recursive code, it buffered the output in the same way but bugged the kernel a whole lot more in-between writes. Not exactly sure what is going on: poll([{fd=1, events=POLLOUT}], 1, 0) = 1 ([{fd=1, revents=POLLOUT}]) write(1, "11111111111111111111111111111111"..., 8192) = 8192 rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, {tv_sec=0, tv_nsec=920390843}) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, {tv_sec=0, tv_nsec=920666397}) = 0 ... rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 poll([{fd=1, events=POLLOUT}], 1, 0) = 1 ([{fd=1, revents=POLLOUT}]) write(1, "11111111111111111111111111111111"..., 8192) = 8192
- dllthomas 4y agoI'm honestly surprised either of them wind up buffered! That must be a change since I stopped paying as much attention to GHC. I'm also not sure what's going on in the second case. IIRC, at some point historically, a sufficiently tight loop could cause trouble with handling SIGINT, so it might be related to some overagressive workaround for that?