3

I'm very disappointed to discover that my Hello World executable in Haskell is 1.3 mb. This is really unacceptable to me. Am I doing something wrong? What excuse is there for having a hello world executable be so large? Is there a reasonable way to cut this down? The same thing in C is 8 kb.

main = print "Hello, worlds"
Steven2163712
  • 169
  • 2
  • 12
  • 10
    Well, it depends on context. I’m happy to see that a Haskell binary, which includes a runtime support library and garbage collector, takes up such a tiny amount of space (1MB). I’m sad to see that a “hello world” in C takes up such a huge amount of space (8KB). – Jon Purdy Nov 27 '17 at 11:08
  • I also find it a bit larg-ish, but keep in mind that GHC statically links libraries in the executable, at least by default. I guess that if GHC liked libraries dynamically, and if the RTS was also moved to an external shared library (as libc does), the executable would be much smaller. For more complex programs it is not a serious issue, in my experience. – chi Nov 27 '17 at 17:44
  • Jon Purdy, very interesting comment, thank you. Chi, I like looking at the assembly output of my executables. It's a strange fetish that I have. – Steven2163712 Nov 28 '17 at 15:32

3 Answers3

11

You don't say which platform or what version of GHC, so I'm making some guesses here.

  1. By default, GHC does not strip debugging symbols. On Linux you can run the strip utility to remove these. On any platform, you can compile with -optl-s to automatically strip debugging symbols during linking.

  2. Depending on exactly which platform you're on and what version of GHC you have, GHC defaults to statically linking all the Haskell libraries you call, and the Haskell runtime system itself (i.e., the garbage collector, thread scheduler, transaction manager, I/O manager...) If supported for your platform, turning on dynamic linking can result in a significant decrease in executable size.

See also

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220
3

Every Haskell binary ships with a copy of the runtime system (https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts). At any rate, you can reclaim some space by stripping the binary.

ocramz
  • 816
  • 6
  • 18
3

Don't statically link in the libraries (including RTS) into binaries if you want small binaries:

% cat x.c
#include <stdio.h>

int main()
{
    printf("Hello world\n");
}
% gcc x.c && du -h a.out
 12K    a.out
% cat x.hs
main :: IO ()
main = putStrLn "Hello world"
% ghc -dynamic x.hs && du -h x
[1 of 1] Compiling Main             ( x.hs, x.o ) [flags changed]
Linking x ...
 16K    x
Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166