为什么在使用之前初始化变量比未初始化变量更快

时间:2014-12-10 08:27:18

标签: c linux

例如,下面i代码中的变量C

t03a.c:

#include <stdio.h>
int main(void)
{
    int a=0;
    int b=1;
    int i=0;//When a variable is declared,the variable is initialised
    for(i=0;i<1000000000;++i);
    return 0;
}

t03b.c:

#include <stdio.h>
int main(void)
{
    int a=0;
    int b=1;
    int i;    // not initialized
    for(i=0;i<1000000000;++i);
    return 0;
}

结果(由linux时间测试):

t03a:
real    0m0.527s
user    0m0.250s
sys     0m0.004s

t03b:
real    0m2.499s
user    0m2.431s
sys     0m0.003s

当然,我多次进行测试。为什么t03a比t03b快?

4 个答案:

答案 0 :(得分:0)

我已经进行了几次测试。以下是两个程序的非常平均的结果:

[xxx@arch-desktop: ~/]$ time ./t03a
real    0m2.819s
user    0m2.817s
sys     0m0.000s
[xxx@arch-desktop: ~/]$ time ./t03b
real    0m2.815s
user    0m2.813s
sys     0m0.000s

gcc -std=c99 -o t03a t03a.c一起编译。也许您可以尝试使用优化参数(即-O3)。

如果以正确的方式编译,我认为不应该有任何区别。直接声明和定义它不应该与以后定义它有任何不同。

答案 1 :(得分:0)

在我的机器(带有gcc的Intel x86)上,两个例程都编译成几乎相同的程序集。唯一的区别是在第二个例子中将0放在堆栈上两次。我无法想象这需要花费很多时间。

使用-O1编译,我为这两个示例提供了相同的(如果不是特别有用)代码。

答案 2 :(得分:0)

在我的情况下,来自t03a.c的汇编代码与t03b.c相同,但是还有一条指令,所以我猜你正在做其他的事情,调度程序给了另一个进程更多的执行时间或者可能是另一个原因,然而,执行时间并不是很大,而且差别不大于结论,差异只是一条指令(你必须认为你在不到3秒的时间内做了1000000000条指令,所以1条指令不会产生影响。

.file   "t03b.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, -8(%rbp)
    movl    $1, -12(%rbp)
    movl    $0, -4(%rbp)
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -4(%rbp)
.L2:
    cmpl    $999999999, -4(%rbp)
    jle .L3
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-7)"
    .section    .note.GNU-stack,"",@progbits

    .file   "t03b.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, -8(%rbp)
    movl    $1, -12(%rbp)
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -4(%rbp)
.L2:
    cmpl    $999999999, -4(%rbp)
    jle .L3
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-7)"
    .section    .note.GNU-stack,"",@progbits

答案 3 :(得分:0)

Initialize是代码样式和避免一些null和逻辑错误的有用实践。 所以这是初始化的主要范围。

但是对于我的测试,t03a.c和t03b.c在Linux体系结构上的性能差异没有显着差异。

小心分析结果,因为CPU,主板和等等的温度也会影响编译时间(如果想要在差异很小的情况下展示你的断言,则需要采取相对和绝对误差)