为什么 strcmp 比我的函数快这么多? [英] Why is strcmp so much faster than my function?

查看:92
本文介绍了为什么 strcmp 比我的函数快这么多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个函数,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 速度.如果之前 strcmpx750 倍,现在只有 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.cusing 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆