1

The following Haskell code for multiplying an Int by 2, when compiled with GHC 8.10.7 via ghc --make main.hs -O3, generates a binary of 3.3M

main :: IO ()
main = do
  str <- getLine
  let n = read str :: Int
  print $ n*2
  return ()

whereas the following C++ code, compiled with GCC 11.2.0 via g++ -std=c++20 main.cpp -O3, generates a binary of only 16K:

#include <iostream>

int main() {
    int n;
    std::cin >> n;
    std::cout << 2*n << std::endl;
}

I tried to make the two programs as similar as I could (but please, tell me if one or both of them can be further simplified):

  • both read from stdin and write to stdout;
  • I believe for both of them input undergoes a string-to-int conversion (after all the command line is made of strings, not numbers), despite the conversion is explicit in Haskell and "hidden" in C++;
  • both use a relatively simple data type: int looked like a good choice in C++, and in Haskell I made a choice which to me looks similar (Integer would have probably been unfair).

Now I have to admit that I know very little about what actually a compiler does, so I can't be sure that the two programs above are as thin as they can be, but still, ... 200 times bigger executable for Haskell?

I've also compiled on Compiler Explorer both the C++ version and the Haskell, and I see that the assembly is ~50 lines for the former, whereas it is 260 lines for the latter.

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 3
    FYI `g++ -o main.cpp -static-libstdc++ -static-libgcc -O3` generates a binary of 9257640 bytes on my machine. This is not stripped mind you. Stripping reduces the size drastically in both cases. OTOH `ghc --make -dynamic main` generates a binary of 15KB. – n. m. could be an AI May 07 '22 at 18:55
  • I was wondering where my sample cpp file had gone. Answer: `-o main.cpp` :D – Enlico May 07 '22 at 19:11
  • :( Sorry editing error. I don't really call my files `main.cpp`. But you have a copy it right here in the post :) – n. m. could be an AI May 07 '22 at 19:19
  • @n.1.8e9-where's-my-sharem. No worries, ahahah :D – Enlico May 07 '22 at 19:30
  • 1
    *Even if* this was a fair comparison, there's just no reason to believe that the 200x scales. This is the problem with microbenchmarks. For all you know, the size of the Haskell executable is just always 3M bigger than the C++ one, regardless of how big the C++ one is; or, it could even scale the other way, with C++ programs growing twice as fast (but starting smaller). One data point just isn't enough to really know anything interesting. – Daniel Wagner May 07 '22 at 20:03
  • @DanielWagner except that if one program accomplishes a task with a few kilobytes, the other one is uselessly big, if it just accomplishes the same task. – Enlico May 07 '22 at 20:07

0 Answers0