为什么如果(i)花费的时间多于(0!= i)

时间:2017-08-16 12:44:34

标签: c

为什么如果(i)花费的时间多于if(0!= i),请建议哪种方法可以检查函数的参数。

请在下面找到代码段:

#include <sys/time.h>
#include <stdio.h>

int main()
{
    struct timeval  lBefore,lAfter,lResult;
    int i,j = 0;

    timerclear(&lBefore);
    timerclear(&lAfter);

    gettimeofday(&lBefore,NULL);

    for(i = 0; i < 0xFFFFFF; i++)
    {
        if(i)
        {
            j++;
        }
    }

    gettimeofday(&lAfter,NULL);

    timersub(&lAfter,&lBefore,&lResult);

    printf("[%d]%ld:%ld\n",j,lResult.tv_sec,lResult.tv_usec);

    j = 0;

    gettimeofday(&lBefore,NULL);

    for(i = 0; i < 0xFFFFFF; i++)
    {
        if(0 != i)
        {
            j++;
        }
    }

    gettimeofday(&lAfter,NULL);

    timersub(&lAfter,&lBefore,&lResult);

    printf("[%d]%ld:%ld\n",j,lResult.tv_sec,lResult.tv_usec);

    return 0;
}

代码输出:

sh-4.2$ main
  

[16777214] 0:79030个
  [16777214] 0:55605个
  sh-4.2 $ main
  [16777214] 0:76910个
  [16777214] 0:53657个
  sh-4.2 $ main
  [16777214] 0:74696个
  [16777214] 0:51295

2 个答案:

答案 0 :(得分:3)

这不是事实。代码完全一样。已经检查了4个热门编译器:

示例gcc x86-64

-O0

if(i)
    cmp     DWORD PTR [rbp-4], 0
    je      .L3

if(0 != i)
    cmp     DWORD PTR [rbp-4], 0
    je      .L7

-O3

if(i) ....
    test    rax, rax
    lea     ebx, [rdx+1]
    jne     .L13
    mov     ebx, edx
    jmp     .L3

if(0 != i) ...
    test    rax, rax
    lea     ebx, [rdx+1]
    jne     .L15
    mov     ebx, edx
    jmp     .L6

PS我讨厌这种荒谬的形式0 != i而不是i != 0

PS2可能在宇宙的某个地方存在C编译器为这些条件生成不同的代码,但i完全等同于i != 0所以很难想象,但一切皆有可能。

答案 1 :(得分:0)

这是错的,但你的方法有缺陷。您应确保您的程序一次只执行一次测试,并确保执行循环 。这是一个修正版本,可以纠正这些方法问题:

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>

int test1(void)
{
    int j = 0;
    int i;
    for(i = 0; i < 0xFFFFFF; i++)
    {
        int x = rand();
        if(x)
        {
            j++;
        }
    }
    return j;
}

int test2(void)
{
    int j = 0;
    int i;
    for(i = 0; i < 0xFFFFFF; i++)
    {
        int x = rand();
        if(0 != x)
        {
            j++;
        }
    }
    return j;
}

int main(int argc, char **argv)
{
    int which = 0;
    if (argc>1) which = atoi(argv[1]);
    srand(1);

    struct timeval lBefore,lAfter,lResult;

    timerclear(&lBefore);
    timerclear(&lAfter);
    gettimeofday(&lBefore,NULL);

    int j = which ? test2() : test1();

    gettimeofday(&lAfter,NULL);
    timersub(&lAfter,&lBefore,&lResult);
    printf("[%d]%ld:%ld\n",j,lResult.tv_sec,lResult.tv_usec);   
}

您链接的网站上的结果:

sh-4.2$ main 0
[16777215]0:199145
sh-4.2$ main 0
[16777215]0:211709
sh-4.2$ main 0
[16777215]0:193211
sh-4.2$ main 0
[16777215]0:184544
sh-4.2$ main 0
[16777215]0:196465
sh-4.2$ main 1
[16777215]0:202904
sh-4.2$ main 1
[16777215]0:206235
sh-4.2$ main 1
[16777215]0:183214
sh-4.2$ main 1
[16777215]0:203317
sh-4.2$ main 1
[16777215]0:207389

所以你看到它没有任何区别。