Tue, 19 Dec 2006

The Size of 'cp'.

Conrad Parker blogged recently showing some simple examples in Haskell. I've been wanting to learn Haskell for a while so I took special interest in Conrad's post. For instance, the program implementing the basic functionality of the Unix cp in Haskell is small and extremely elegant:

  import System.Environment

  main = do
      [infile, outfile] <- getArgs
      s <- readFile infile 
      writeFile outfile s

However, on my machine (i686 laptop running Ubuntu Edgy), the generated executable is 1.5 megabytes in size even after being stripped. By way of contrast, the /bin/cp executable written in C is 56 kilobytes. WTF?

So lets look at the Ocaml version:

  let _ =
      let srcfile = open_in Sys.argv.(1) in
      let destfile = open_out Sys.argv.(2) in
      let maxlen = 8192 in
      let str = String.create maxlen in
      let count = ref 1 in
      while !count > 0 do
          count := input srcfile str 0 maxlen ;
          output destfile str 0 !count ;

This is pure imperative code and doesn't use any of the functional language features of Ocaml, but it compiles to a 79 kilobyte stripped executable. Compared to the C executable, the Ocaml executable is 40% bigger and the Haskell one is 2500% bigger.

Obviously, the size of the executable is not the only determining factor in choice of programming language, but Haskell's executables do seem unreasonably large.

Update here.

Posted at: 21:15 | Category: CodeHacking | Permalink