I have the following simple code and when I compiling them in GCC and Clang there is a huge performance difference between theirs execute times as you can see the results and the versions of the compilers below.
char* strchr_x(register const char* s, int c) {
do {
if (*s == c) {
return (char*)s;
}
} while (*s++);
return 0;
}
char* get(char* value, const char separator) {
int separator_index = strchr(value, separator) - value;
char* result = malloc(separator_index);
memcpy(result, value, separator_index);
result[separator_index] = '\0';
return result;
}
int main() {
const char separator = ',';
clock_t t = clock();
for (size_t i = 0; i < 100000000; ++i) {
free(get("127.0.0.1, 127.0.0.2:1111", separator));
}
float elapsed_seconds = (((double)(clock() - t)) / CLOCKS_PER_SEC);
printf("%f seconds.\n", elapsed_seconds);
return 0;
}
gcc version 8.1.0 (Ubuntu 8.1.0-5ubuntu1~16.04)
# gcc main.c -O3 -o gcc-main
# 1.968750 seconds.
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
# clang main.c -O3 -o clang-main
# 0.000000 seconds.
Additionally, the 'strchr_x' implementation is exactly the same with original GCC implementation. You can see it at https://github.com/gcc-mirror/gcc/blob/master/libiberty/strchr.c
When I use the 'strchr' method in the standard library; GCC's run time reducing to 0.015625 seconds.
So, my questions are:
If you take your code and plug it into https://godbolt.org/ you can see that Clang will optimize away the entire for loop, which explains why it executes in 0 seconds. It likely does that because the only side effect of get is a malloc, and the result is freed immediately.
EDIT: GCC really doesn't do too well with your code it seems... I have checked the generated assembler again, and it's not just that it fails to remove the empty for loop (for strchr()), but it also fails to remove the function calls in the body of the loop (for strchr_x()).
So in the end it all boils down to some pretty strange optimization behavior, and your slowest example is actually the only one that does anything at all. I don't know why GCC fails so hard on your example, but i definitely agree that you should file this as a bug (maybe even two separate bugs, since it already fails hard when using strchr(), and even harder when using strchr_x(), even though both should be identical)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With