我知道'静电'是关于范围的,但我有一个问题:访问哪个功能/变量会更快:一个静态的'一个与否? 哪个代码会更快:
#include <stdio.h>
int main(){
int count;
for (count=0;count<1000;++count)
printf("%d\n",count);
return 0;
}
或
#include <stdio.h>
int main(){
static int count;
for (count=0;count<1000;++count)
printf("%d\n",count);
return 0;
}
在我的代码中,我处理的是非常大的数字(使用无符号长整数),并且我每秒访问和增加它们大约4.000.000次。 此代码不是我正在处理的代码,它只是一个示例。
答案 0 :(得分:1)
作为善意的表示,我已经编制了一个我们可以实际推理的程序。
#include <stdint.h>
#include <stdio.h>
int
main()
{
static const uint64_t a = 1664525UL;
static const uint64_t c = 1013904223UL;
static const uint64_t m = (1UL << 31);
static uint32_t x = 1;
register unsigned i;
for (i = 0; i < 1000000000U; ++i)
x = (a * x + c) % m;
printf("%d\n", x);
return 0;
}
它将简单地计算由简单线性同余生成器返回的伪随机序列的十亿分之一元素。我们必须做一些比简单地递增计数器更难的事情,否则编译器将优化整个循环。
以下是我编译的方法(x86_64 GNU / Linux上的GCC 4.9.1):
$ gcc -o non-static -Dstatic= -Wall -O3 main.c
$ gcc -o static -Wall -O3 main.c
要获取不带static
的版本,我们只需在编译器命令行上#define
。
运行这两个程序需要2.36秒,这意味着没有可衡量的性能差异。
为了找出原因,我想查看汇编代码。
$ gcc -S -o non-static.s -Dstatic= -Wall -O3 main.c
$ gcc -S -o static.s -Wall -O3 main.c
我们发现GCC为内循环生成了相同的机器代码,并将static
变量的特殊处理移出循环,这是我们应该从一个好的编译器中得到的。
static
的相关代码:
main:
.LFB11:
.cfi_startproc
movl x.2266(%rip), %esi
movl $1000000000, %eax
.p2align 4,,10
.p2align 3
.L2: # BEGIN LOOP
imull $1664525, %esi, %esi
addl $1013904223, %esi
andl $2147483647, %esi
subl $1, %eax
jne .L2 # END LOOP
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC0, %edi
xorl %eax, %eax
movl %esi, x.2266(%rip)
call printf
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
且没有:
main:
.LFB11:
.cfi_startproc
movl $1000000000, %eax
movl $1, %esi
.p2align 4,,10
.p2align 3
.L2: # BEGIN LOOP
imull $1664525, %esi, %esi
addl $1013904223, %esi
andl $2147483647, %esi
subl $1, %eax
jne .L2 # END LOOP
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
这再次强调了许多人在评论中试图表达的内容:我们需要实际的代码来推理性能,我们应该在这样做的同时对其进行基准测试。
此外,您不必过多担心此类事情并且大多数时候都信任您的编译器。专注于编写可读和可维护的代码,如果您有证据证明有必要达到所需的性能,则只会弄乱脏的细节。在您的特定示例中,我看不到声明局部变量static
的任何有效理由。这让读者感到不安,不应该这样做。