You are comparing file IO, string to int, raw processing, and text output speed all at the same time.
There are pros and cons associated with the choices made in both sets of libraries and compilers for each of those aspects.
What exactly are you trying to measure? Can you isolate those parts more specifically and compare them instead? That would probably be more informative.
Spoiler: the title is clickbait and the article actually says that C isn't really slower.
The initial C implementation written by the author that was passed off as representative of C was naive and had a couple of performance blockers. The author points out those performance blockers, and once the author gets rid of those blockers and re-tests te conclusion is that C isn't actually slower.
Ignoring calling out into badly implemented external functions (like stdlib stuff), solving the same problem in any statically typed and compiled systems programming language should pretty much result in the same machine code output, any remaining differences are down to the compiler implementation, not the programming language.
One of the things that actually can make a difference is different rules for pointer aliasing so that the compiler isn't forced to go through memory in some cases, but as Rust has shown, fixing this on the language level doesn't seem to make all that much of a difference in real world performance.
In rust's case part of that is that LLVM is very C optimized. It's not great at taking advantage of the more strict rules of rust yet. It is getting better though.
If you read the article you'll learn that in the end the author not only states there isn't any practical difference in the results that the author pulled with their ad-hoc test examples but also points out which non-performant choices were intentionally left in the last example that lead to the 40ms difference (which, again, the author states in no uncertain terms is meaningless)
I don't know how anyone can look at benchmarks of two ad-hoc tests with one of them being intentionally and openly sub-optimal and from that point automatically jump to conclusions over performance traits of a whole programming language. Crazy stuff.
Don't @ me about my crappy C code (I haven't written C proper in a few years), but I unga-bunga'd together a version that is over twice as fast as the one in the article using POSIX extensions:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int arraySize = 4096;
char*array = (char*)realloc(0, arraySize);
int f = open("/tmp/numbers", O_RDONLY);
if (f < 0) { return EXIT_FAILURE; }
struct stat fstat;
stat("/tmp/numbers", &fstat);
char* buf0 = mmap(NULL, fstat.st_size, PROT_READ, MAP_PRIVATE, f, 0);
char* buf = (char*) buf0;
int i = 0;
for (; buf < buf0 + fstat.st_size;)
{
if (i >= arraySize) {
arraySize *= 2;
array = (char*) realloc(array, arraySize);
}
int sv = 0;
unsigned long value = 0;
for (;;sv=1) {
int c = *buf++ - '0';
if (c < 0 || c > 9)
break;
value = value * 10 + c;
}
if (sv) {
array[i++] = (value & 7) + '0';
}
}
array[i++] = '\n';
fwrite(array, 1, i, stdout);
}
$ time ./mmap-ver | sha1sum
9fb65214d11697bf66753db443edb017b7f08fdf -
real 0m0.346s
user 0m0.304s
sys 0m0.060s
$ time ./second-article-ver | sha1sum
9fb65214d11697bf66753db443edb017b7f08fdf -
real 0m1.168s
user 0m1.019s
sys 0m0.028s
I don't know the context of why you guys are doing these microbenchmarks, but consider doing proper custom buffering for high speed number conversion. Or at least use fgetc_unlocked() / fputc_unlocked().
The normal FILE reading functions take a lock, which is quite slow for single-byte reads and writes.
Can't see a good reason for the locking either, other than that printf is commonly used for debugging, which without locking would probably leave a lot of users puzzled with random crashes in multithreaded scenarios.
Better title: why are some C stdlib functions slower than some Bolin stdlib functions. Unlike with many other languages, it's totally fine to write C code and (almost) completely ignore the stdlib functions. The C stdlib is essentially just the least common denominator to get trivial cmdline tools working (badly) across platforms, but that's about it.
I think there is merit to these discussions. One has to ask what the most natural/idiomatic program to solve a problem is, and sometimes the performance of that matters more than the utmost performance you can get from the language.
I'm know to be a rust fanboy, so I'll talk about C++ instead. C++ is known to be fast, but theres also some known logic that you should use smart pointers to have more memory safety than raw pointers. If you follow that you'll end up with a slower program. Of course, you can remove those and manage the pointers yourself, but then you have to deal with documenting the lifetimes properly.
These are trade offs people agree to when using a language. The easier thing might be slower and that's ok. Speed isn't always critical, so you can't exactly rate languages by that metric alone
> but theres also some known logic that you should use smart pointers to have more memory safety than raw pointers. If you follow that you'll end up with a slower program.
That would be true for std::shared_ptr, but not for std::unique_ptr. You would/should only use the former if you're dealing with true shared ownership.
Nobody understands C use fgets when he/she wants speed.
The whole point of C is the programmer decides the performance himself, not trying to the fastest. None of the popular languages consistently deliver this.
According to the website [1] there is a strict license to this programming language.
> The License is intended for free learning and hobbyists and is a personal use license which means the Software may be installed and run only on Licensee computer as required for the purposes of Licensee’s code to produce a binary executable output (the “Executable Product”) only on Licensee-controlled Endpoint. An Endpoint is defined as a computer operating system (“OSE”) of any type physically hosted, but limited to Licensee’s internal personal use and not for distribution or any other use. For certainty, Licensee may not: distribute, assign, sell or grant any rights in or to the Software OR the binary executable product created by using the Software.
People of course can license the fruits of their labor however they wish to, I just can’t understand why someone would license their compiler in a way that prohibits me from sharing a useful program I made with my family or friends.
23 comments
[ 0.19 ms ] story [ 63.5 ms ] threadThe initial C implementation written by the author that was passed off as representative of C was naive and had a couple of performance blockers. The author points out those performance blockers, and once the author gets rid of those blockers and re-tests te conclusion is that C isn't actually slower.
The C++, rewritten correctly (see sibling comment), is substantially faster than the Bolin code.
One of the things that actually can make a difference is different rules for pointer aliasing so that the compiler isn't forced to go through memory in some cases, but as Rust has shown, fixing this on the language level doesn't seem to make all that much of a difference in real world performance.
AFAIK, for now, Rust's mutable no alias is only used at function parameters, so, for now, its use is pretty limited.
If you read the article you'll learn that in the end the author not only states there isn't any practical difference in the results that the author pulled with their ad-hoc test examples but also points out which non-performant choices were intentionally left in the last example that lead to the 40ms difference (which, again, the author states in no uncertain terms is meaningless)
I don't know how anyone can look at benchmarks of two ad-hoc tests with one of them being intentionally and openly sub-optimal and from that point automatically jump to conclusions over performance traits of a whole programming language. Crazy stuff.
But "this PHP program is faster than that C program" is a lot less of a shocking headline than "PHP is faster than C".
So, why is Bolin slower (and longer) than C++? And why is so much of published code so bad?
But I bet just transcribing the C++ code to the most naïve C code would go as fast as the C++.
So, go figure, again.
The normal FILE reading functions take a lock, which is quite slow for single-byte reads and writes.
I had forgotten that C got such a dumb change.
I am kind of surprised you have a machine that can run as slow as yours does. Is it RPI or something?
I'm know to be a rust fanboy, so I'll talk about C++ instead. C++ is known to be fast, but theres also some known logic that you should use smart pointers to have more memory safety than raw pointers. If you follow that you'll end up with a slower program. Of course, you can remove those and manage the pointers yourself, but then you have to deal with documenting the lifetimes properly.
These are trade offs people agree to when using a language. The easier thing might be slower and that's ok. Speed isn't always critical, so you can't exactly rate languages by that metric alone
That would be true for std::shared_ptr, but not for std::unique_ptr. You would/should only use the former if you're dealing with true shared ownership.
The whole point of C is the programmer decides the performance himself, not trying to the fastest. None of the popular languages consistently deliver this.
> The License is intended for free learning and hobbyists and is a personal use license which means the Software may be installed and run only on Licensee computer as required for the purposes of Licensee’s code to produce a binary executable output (the “Executable Product”) only on Licensee-controlled Endpoint. An Endpoint is defined as a computer operating system (“OSE”) of any type physically hosted, but limited to Licensee’s internal personal use and not for distribution or any other use. For certainty, Licensee may not: distribute, assign, sell or grant any rights in or to the Software OR the binary executable product created by using the Software.
People of course can license the fruits of their labor however they wish to, I just can’t understand why someone would license their compiler in a way that prohibits me from sharing a useful program I made with my family or friends.
[1] https://bolinlang.com/eula