- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道“静态”与范围有关,但我有一个问题:什么函数/变量访问速度更快:“静态”或不是?哪个代码会更快:
#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;
}
在我的代码中,我正在处理非常大的数字(带有 unsigned long long),并且我每秒访问和增加它们大约 4.000.000 次。 此代码不是我正在处理的代码,它只是一个示例。
最佳答案
作为善意的标志,我编写了一个我们可以实际推理的程序。
#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
的任何有效理由。作为一名读者,这让我感到不安,不应该这样做。
关于c - 有和没有 'static' 的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27446881/
我是 F# 的菜鸟,目前正在阅读 F# 3.0 中的专家。 它是我学习的第一种编译语言(我只知道用 R 编程) 在第 6 章第 117 页,我们没有太多仪式性地介绍 静态让和静态成员。我真的不明白它是
我很迷茫。我已经花几个小时广泛地复习了我的两个类(class)。没有什么是静态的,没有什么是静态引用的,但我无法摆脱这个错误。 A 类文件 (ClassA.php) privateVariable =
关于类公共(public)类声明,请看这两段代码: public class Helper { public static void CallMeganFox(string phoneNumb
我如何使用“super”关键字从父类(super class)(类“aa”)引用“a1” class aa { protected static int a1 = 2; } public class
class Perkusja { boolean talerze = true; boolean beben = true; void zagrajNaBebnie() { Sys
我试图在编译 C++ 程序时静态链接库。 g++ (GCC) 4.8.5 20150623(红帽 4.8.5-4) $ g++ -std=c++11 -I/home/jerry/Desktop/tin
$ javac TestFilter.java TestFilter.java:19: non-static variable this cannot be referenced from a sta
这个问题在这里已经有了答案: How do I create a global, mutable singleton? (7 个答案) How can you make a safe static
“覆盖”静态数组时我遇到了一个棘手的问题。我有静态数组(为简单起见),它们在不同的派生类中具有固定长度,但在编译时仍然知道所有大小。我在基类中也有一个虚函数,但我不知道如何解决在派生类中覆盖这些数组和
我刚刚在遗留代码中发现了这一点。我知道使用宏,每当使用名称时,它都会被宏的内容替换。它们最常用于为数字常量提供符号名称。我所知道的是预处理没有类型安全、范围的概念。 这样做的真正好处是什么? #def
将 Singleton 实例声明为 static 还是声明为 static final 更好? 请看下面的例子: 静态版本 public class Singleton { private s
问题: 我观察到的行为是 TypeScript 的预期行为吗? 我观察到的行为是 ECMAScript 6 的预期行为吗? 是否有一种简单的方法可以返回继承层次结构以处理每个级别的“myStatic”
在php中,访问类的方法/变量有两种方法: 1. 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/functi
我尝试向 ExpandoObject 添加一个动态方法,该方法会返回属性(动态添加)给它,但它总是给我错误。 我在这里做错了吗? using System; using System.Collecti
我试图获得一个静态链接到我的程序的音频库。我用 this灵活的包。为了让它运行,我必须按照描述构建 soloud 库 here .下载后不久,我在“build”文件夹中运行了“genie --with
这是我的webpack.prod.config.js代码 const path = require('path'); const { CleanWebpackPlugin } = require('c
我想知道什么时候应该对变量和(或)方法使用静态、最终、静态最终参数。据我了解: final:类似于c++中的const参数。它基本上意味着值(或在方法中 - 返回值)不会改变。 静态:这意味着值(或方
我一直在阅读有关使用静态对象作为锁的内容,最常见的示例如下: public class MyClass1 { private static final Object lock = new Obje
在 Visual Basic 2008 中,我知道有两种不同的方法可以完成同一件事: 成员(member)级别的 Dim: Dim counter1 as integer = 0 Dim counte
static public final int i = 0; public static final int i = 0; 两者都工作正常。 为什么同样的事情可以用两种不同的风格来完成? 最佳答案 因
我是一名优秀的程序员,十分优秀!