4 ms·
When I run the "faster" C code, it takes 176 ms. When I run this C++ code: #include <iostream> #include <fstream> int main() { auto& out = *std::cout
by ncmncm 4y ago
When I run the "faster" C code, it takes 176 ms. When I run this C++ code:
#include <iostream>
#include <fstream>
int main() {
auto& out = *std::cout.rdbuf();
std::filebuf in;
in.open("/tmp/numbers",
std::ios::in);
for (int c, n = 0;
(c = in.snextc()) != EOF;) {
if (c != '\n') {
n = n * 10 + (c - '0');
} else {
out.sputc((n & 7) + '0'), n = 0;
}
}
std::cout << '\n';
}
it takes 84 ms (and presumably 90 ms on the author's machine).
So, why is Bolin slower (and longer) than C++? And why is so much of published code so bad?
- marginalia_nu 4y agoDon'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
- ncmncm 4y agoYet, still slower than the C++ code. But I bet just transcribing the C++ code to the most naïve C code would go as fast as the C++.
- marginalia_nu 4y agoI get these times for your C++ real 0m0.854s user 0m0.564s sys 0m0.054s
- ncmncm 4y agoI am corrected.
- ncmncm 4y agoCuriously, when I did transcribe the C++ code to C: #include <stdio.h> int main() { FILE* in = fopen("/tmp/numbers", "r"); for (int c, n = 0; (c = getc(in)) != EOF;) { if (c != '\n') { n = n * 10 + (c - '0'); } else putchar((n & 7) + '0'), n = 0; } putchar('\n'); } it takes 233 ms instead of the expected 84 ms. So, go figure, again.
- jstimpfle 4y agoI 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.