Here is my code.
foo()
is simple. It compares the argument to some strings one by one.
main()
is a little complex. It just call foo()
with different strings and time it, 3 times.
#include <string.h>
#include <time.h>
#include <stdio.h>
int foo(const char *s)
{
int r = 0;
if (strcmp(s, "a11111111") == 0) {
r = 1;
} else if (strcmp(s, "b11111111") == 0) {
r = 2;
} else if (strcmp(s, "c11111111") == 0) {
r = 3;
} else if (strcmp(s, "d11111111") == 0) {
r = 4;
} else if (strcmp(s, "e11111111") == 0) {
r = 5;
} else if (strcmp(s, "f11111111") == 0) {
r = 6;
} else if (strcmp(s, "g11111111") == 0) {
r = 7;
}
return r;
}
int main()
{
char *ss[] = {
"a11111111",
"b11111111",
"c11111111",
"d11111111",
"e11111111",
"f11111111",
"g11111111",
"h11111111",
};
int r = 0;
for (int i = 0; i < 3; i++) {
clock_t begin = clock();
for (int j = 0; j < 100000; j++) {
r = foo(ss[r]);
}
printf("%lu\n", clock() - begin);
}
return r;
}
Here is the result:
$ gcc tmp.c
$ ./a.out
3979
4025
4272
$
$ gcc tmp.c -O2
$ ./a.out
20575
14572
13841
$
As you can see, -O2
makes the code much slower. Why?
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)
Thanks in advance,
Wu
==== EDIT ====
Thanks @Ville Krumlinde. I make another code to test strcmp
only.
There are 2 files:
//// main.c
#include <time.h>
#include <stdio.h>
int x_strcmp(const char *a);
int main()
{
int r = 0;
for (int i = 0; i < 3; i++) {
clock_t begin = clock();
for (int j = 0; j < 100000; j++) {
r += x_strcmp("a111111111");
}
printf("%lu\n", clock() - begin);
}
return r;
}
//// tmps.c
#include <string.h>
int x_strcmp(const char *a)
{
return strcmp(a, "a11111111");
}
The result:
$ gcc main.c -O2 -c
$
$ gcc tmps.c -c && cc main.o tmps.o -o a.out
$ ./a.out
870
896
857
$
$ gcc tmps.c -c -O2 && cc main.o tmps.o -o a.out
$ ./a.out
6290
5191
6382
$
The only difference is with or without -O2
when compiling tmps.c
.
And the flag still makes the code much slower.
Here are the assembly code:
#without -O2
x_strcmp:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movl $.LC0, %esi
movq %rax, %rdi
call strcmp
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
# with -O2
x_strcmp:
.LFB24:
.cfi_startproc
movq %rdi, %rsi
movl $10, %ecx
movl $.LC0, %edi
repz cmpsb
seta %al
setb %dl
subl %edx, %eax
movsbl %al, %eax
ret
.cfi_endproc