This comparison should be taken with some rather large grains of salt...
`(float)rand()/(float)RAND_MAX` is not a good way to generate random floating-point values in C. The values will be in [0,1] but they will not be perfectly uniform. rand() returns a positive `int` and thus only uses about 31-bits of entropy. This is both too much and too little: C floats in [0,1) only have 22 bits or entropy, so you're wasting entropy; on the other hand, all the other codes produce random 64-bit floats (i.e. C doubles), which have 52 bits of entropy, so the C code is generating only 60% as much entropy as the other codes. Instead one should use a function like drand48 which produces a 64-bit C double.
These implementations are all using very different pseudo-random number generation algorithms with very different performance characteristics and qualities. The best is likely the Mersenne Twister algorithm used by PHP – that's the gold standard for non-cryptrographic PRNGs. Others use linear congruential and xor-shift algorithms, which are faster and not as good (easier to distinguish form true randomness).
Some variants of XorShift (including the one used by Rust, I believe) are not only faster and much smaller than MT19973 but also produce higher quality numbers. See http://xorshift.di.unimi.it/
This amounts to a nice benchmark of various implementations of rand() ^_^
Generally, a language in and of itself doesn't have performance characteristics. What you are measuring is the quality of the output of it's compiler. While he indicates PHP is way at the back of the pack, I'd guess that a few years ago JavaScript would be right there with it, but by designing sufficiently advanced compilers you can make any programming language fast.
I remember reading a few years ago that on MacOS X (PowerPC), code generated by IBM XLC was some 50% faster than that generated by GCC for some benchmark (this was before LLVM) -- and that was on the same exact language.
I would agree that this is a test of rand().
There is no significant difference in the workload... other than the library implementations of the rng.
All the lower-level compilers (C,Go,Rust) should be producing effectively the same code for this which then calls out to the ir library rng. I strongly suspect the time is dominated by the rng duration.
Maybe someone should benchmark the rng??
Running the original on my machine (compiled with VS2013) takes 3.75 seconds. Changing the comparison to (x * x + y * y) <= 1.0 (no need for the sqrt since we are comparing with 1!) takes the runtime down to 2.87 seconds. Switching the accumulation from a branch to hits+=in_circle(r1, r2) further reduces it to 2.43 seconds.
To be fair, all of the codes use sqrt, so if you're going to do clever hand-optimizing in the C version, then you should do the same in the other ones too.
As the author points out in their final paragraph, this particular experiment is not an ideal benchmark for comparing language performance and should not, on its own, be used to make language choices.
But it did show some interesting results. The 7x speedup by using PyPy instead of cPython was interesting. Gccgo being 2x faster than Go caught my eye.
`(float)rand()/(float)RAND_MAX` is not a good way to generate random floating-point values in C. The values will be in [0,1] but they will not be perfectly uniform. rand() returns a positive `int` and thus only uses about 31-bits of entropy. This is both too much and too little: C floats in [0,1) only have 22 bits or entropy, so you're wasting entropy; on the other hand, all the other codes produce random 64-bit floats (i.e. C doubles), which have 52 bits of entropy, so the C code is generating only 60% as much entropy as the other codes. Instead one should use a function like drand48 which produces a 64-bit C double.
These implementations are all using very different pseudo-random number generation algorithms with very different performance characteristics and qualities. The best is likely the Mersenne Twister algorithm used by PHP – that's the gold standard for non-cryptrographic PRNGs. Others use linear congruential and xor-shift algorithms, which are faster and not as good (easier to distinguish form true randomness).