为什么 strcmp 比我的函数快这么多? [英] Why is strcmp so much faster than my function?
问题描述
我写了一个函数,Str::Compare
,它基本上是以另一种方式重写的strcmp
.比较这两个函数时,在重复 500'000'000 次的循环中,strcmp
执行速度太快,大约快 x750 倍.
I wrote a function, Str::Compare
, that is basically a strcmp
rewritten in another way.
While comparing the two function, in a loop repeted 500'000'000 times, strcmp
execute too much fast, about x750 times faster.
此代码是在 C 库中编译的,-Os
参数处于活动状态:
This code was compiled in a C library with -Os
parameter active:
int Str::Compare(char* String_1, char* String_2)
{
char TempChar_1, TempChar_2;
do
{
TempChar_1 = *String_1++;
TempChar_2 = *String_2++;
} while(TempChar_1 && TempChar_1 == TempChar_2);
return TempChar_1 - TempChar_2;
}
那个函数的执行时间是3.058s
,而strcmp
只有0.004s
.
The execution time of that function is 3.058s
, while strcmp
only 0.004s
.
为什么会这样?
这也是我实现基准循环的方式:
Also this is how I implemented the benchmark loop:
int main()
{
char Xx[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"},
Yy[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"};
for(int i = 0; i < 500000000; ++i)
Str::Compare(Xx, Yy);
}
编辑:在测试我编写的一些代码并进行优化时,大大提高了 Str::Compare
速度.如果之前 strcmp
是 x750 倍,现在只有 x250.这是新代码:
Edit:
While testing some code I wrote and optimization that improved drastically Str::Compare
speed.
If before strcmp
was x750 times faster now is only x250. This is the new code:
int Str::Compare(char* String_1, char* String_2)
{
char TempChar_1, TempChar_2, TempChar_3;
while(TempChar_1 && !TempChar_3)
{
TempChar_1 = *String_1++;
TempChar_2 = *String_2++;
TempChar_3 = TempChar_1 ^ TempChar_2;
}
return TempChar_1 - TempChar_2;
}
新的执行时间为0.994s
.
推荐答案
我很好奇并构建了一个测试程序:
I was curious about it and build a test program:
#include <string.h>
compare(char* String_1, char* String_2)
{
char TempChar_1,
TempChar_2;
do
{
TempChar_1 = *String_1++;
TempChar_2 = *String_2++;
} while(TempChar_1 && TempChar_1 == TempChar_2);
return TempChar_1 - TempChar_2;
}
int main(){
int i=strcmp("foo","bar");
int j=compare("foo","bar");
return i;
}
我使用 gcc -S -Os test.c
使用 gcc 4.7.3 将其编译为汇编程序,结果如下汇编程序:
I compiled it to assembler with gcc -S -Os test.c
using gcc 4.7.3 resulting in the following assembler:
.file "test.c"
.text
.globl compare
.type compare, @function
compare:
.LFB24:
.cfi_startproc
xorl %edx, %edx
.L2:
movsbl (%rdi,%rdx), %eax
movsbl (%rsi,%rdx), %ecx
incq %rdx
cmpb %cl, %al
jne .L4
testb %al, %al
jne .L2
.L4:
subl %ecx, %eax
ret
.cfi_endproc
.LFE24:
.size compare, .-compare
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "bar"
.LC1:
.string "foo"
.section .text.startup,"ax",@progbits
.globl main
.type main, @function
main:
.LFB25:
.cfi_startproc
movl $.LC0, %esi
movl $.LC1, %edi
call compare
movl $1, %eax
ret
.cfi_endproc
.LFE25:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
.section .note.GNU-stack,"",@progbits
我不太擅长 x86 汇编程序,但据我所知,删除了对 strcmp 的调用,并简单地替换为一个常量表达式( movl $1, %eax
).因此,如果您在测试中使用常量表达式,gcc 可能会将 strcmp 优化为常量.
I am not that good in x86 assembler but as far as I see it the call to the strcmp is removed and simply replaced by a constant expression ( movl $1, %eax
). So if you use a constant expression for your tests, gcc probably optimizes the strcmp to a constant.
这篇关于为什么 strcmp 比我的函数快这么多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!