Crystal Source Code:
def factorial(n)
n < 2 ? 1 : n * factorial(n - 1)
end
if ARGV.size > 0
n = ARGV.first.to_u64
puts factorial(n)
else
puts "No arguments provided"
exit 1
end
C Source Code:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
uint64_t factorial(uint64_t n) {
return (n < 2) ? 1 : n * factorial(n - 1);
}
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("No arguments provided\n");
return 1;
} else {
uint64_t n = strtol(argv[1], NULL, 10);
printf("%lu\n", factorial(n));
return 0;
}
}
It can be seen that the binary produced by Crystal is significantly larger than the C binary:
-rwxr-xr-x 1 daniel daniel 7168 Jun 24 19:46 hello_c
-rw-r--r-- 1 daniel daniel 385 Jun 24 19:49 hello.c
-rwxr-xr-x 1 daniel daniel 1270216 Jun 24 20:02 hello_cr
-rw-r--r-- 1 daniel daniel 177 Jun 24 20:01 hello.cr
177x larger in fact.
@teaearlgraycold big binaries contains a lot of debug info as @akzhan said. It's intend to use on development environment.
On production, you can compile using: (warning: basic debug info is still very useful on production environments)
185600B is 6.8x smaller that a binary compiled without flags release and no-debug (1270216B)
Optionally you can strip symbols to make the binary even more smaller:
strip removes about 30K of unnecessary symbols, then 158344B is about 22X bigger that C binary compared with 177X you got. However Crystal lang is more High level than C and it simplify a lot of things when you code, type inference by example.
Experimenting with smaller binaries
All the above is using standard prelude, you can get even smaller binaries just linking LibC and using empty prelude like:
And then:
8488B is just 1.2X of C binary and if you strip it is like 0.8X of C binary.
You can see a experiment to get an even smaller crystal binary here ๐ https://github.com/kubo39/tinycr (just 146 bytes ๐ )