在函数计算中是否存在使用静态变量的性能问题,是否会影响函数执行的速度,因为静态变量只初始化一次?
问题是高度重复的呼叫优化。
考虑这个例子
int calcme(int a, int b)
{
static int iamstatic = 20;
return a*iamstatic + b;
}
使用static的原因是希望,每次调用函数时,iamstatic都不会被置于堆栈中,并且如果需要,它将被设计为更改。 (省略静态变量代码)
答案 0 :(得分:8)
我认为你可能会降低性能。使用静态时,内存位于程序的bss部分。当调用该函数时,它访问两个不同的位置,即函数存储器和参数存储器。如果它是本地的,那么你可能会因本地化而获得性能,当所有参数都在同一个缓存行时,也就是当cpu读取内存时它读取一个完整的缓存行(16个字节是一个常见的行大小),你读全部一个内存中的数据访问缓存。
答案 1 :(得分:3)
是。在你的例子中,它可能没有帮助(至少足以关心)。事实上,它甚至可能会有点伤害,因为它可能涉及从内存加载数据,而本地可能只涉及将值加载到寄存器中。如果初始化足够慢以使性能变得重要,那么只要初始化一次是可接受的,使变量static
可以提高性能。
答案 2 :(得分:2)
答案在技术上是“否”,因为C标准没有指定它。
效率取决于许多因素,如变量使用和硬件。如果您愿意,您可以编写多次调用的变量函数,以测试差异。在实践中,可能存在非常小且无关紧要的差异。
答案 3 :(得分:1)
这是该功能最具可读性和最高性能的版本。
int calcme(int a, int b)
{
return a*20 + b;
}
如果在static
变量中放置常量,编译器可能会发现它永远不会更改,并将其转换为立即数操作数。也许编译器不会弄清楚它会从内存中加载静态。
如果在全局变量中放置常量,编译器将从内存中加载变量。
你试图超越优化器,这几乎总是一个坏主意。
这是您的原始代码,已编译:
leal (%rdi,%rdi,4), %edi
leal (%rsi,%rdi,4), %eax
ret
这与return a*20 + b;
生成的代码相同,但您的代码更难以阅读。请注意,静态变量实际上并未存储在任何位置,它会转换为立即操作数(然后强度降低会进一步降低它)。您将从以下代码获得相同的性能:
int calcme(int a, int b)
{
int local = 20; // "initialized" every time the function is called
// yet the assembly is the same
return a*local + b;
}
答案 4 :(得分:0)
我不会立即看到任何使用静态变量的性能提升或惩罚。
您可以做的是反汇编两个相同的函数并比较代码或分析每个函数。
答案 5 :(得分:0)
你为什么不做一个简单的
#define MY_CONSTANT 20
/* ... */
return a*MY_CONSTANT + b;
也许编译器知道一个技巧乘以20(当你乘以iamstatic
时它将无法应用。)
答案 6 :(得分:0)
如果使用优化进行编译,则取决于具体情况。
在您的示例中,iamstatic
是常量,我猜速度不会改变。
您应该尝试测量执行时间或查看汇编代码。
答案 7 :(得分:0)
接受的答案是正确的,但也许更重要的是,你不应该根据尝试使其“更快”来选择变量的存储持续时间,而是根据代码的正确语义来选择。
malloc
获取的对象中。