C++ 定义静态全局数组以避免在函数中定义它

C++ 定义静态全局数组以避免在函数中定义它,c++,optimization,static-variables,C++,Optimization,Static Variables,我刚刚开始使用一段代码,作者声称这段代码是“高度优化的”。在某些时候,他们会这样做: namespace somename { static float array[N]; } float Someclass::some_function(std::vector<float>& input) { // use somename::array in some way return result; } 期望性能下降是否合理?换句话说,在许多不同的系统

我刚刚开始使用一段代码,作者声称这段代码是“高度优化的”。在某些时候,他们会这样做:

namespace somename 
{ 
  static float array[N]; 
} 

float Someclass::some_function(std::vector<float>& input) 
{
  // use somename::array in some way 
  return result; 
}

期望性能下降是否合理?换句话说,在许多不同的系统和编译器中,作者的优化(使用全局数组而不是函数中的数组)是否会明显提高性能

唯一的区别是,“数组”是全局分配的(如果声明为静态的),如果在函数体中声明,它将在堆栈上“分配”。这里真正重要的是数组的大小(N)。 如果它是一个大数组,您可以让它保持静态,因为您可能无法在堆栈上声明它。 第三种选择是动态分配它(heap,带有new关键字)。然而,所有这些假设都不会真正影响函数本身的性能,因为一旦分配,这些方法中的任何一种都不会有开销。

因为数字很重要:

./trial2.out 59.08s用户0.01s系统88%cpu 1:07.01总计

/试用59.40s用户0.00s系统99%cpu总计59.556

源代码:(带有注释和测试的备用代码)

所以,没有区别。汇编时使用:

gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
在函数中使用非静态数组时的时间结果:

./trial.out  57.32s user 0.04s system 97% cpu 58.810 total

./trial.out  57.77s user 0.04s system 97% cpu 59.259 total

同样,没有区别。因为当您使用数组时,它是函数堆栈的一部分,而不是堆,所以每次调用函数时保留内存不会产生任何开销。如果您使用动态分配,情况将完全不同(在这种情况下,我确实怀疑性能会有巨大差异)。

也许您没有注意到差异,但有一个!使用
static
关键字,数组存在于程序的数据段中,并保持整个运行时。如果没有
static
关键字,数组将驻留在堆栈中,并在每次调用函数时进行初始化。不过,堆栈版本可能是更好的选择,因为它具有更好的局部性,因此缓存未命中率更低。你必须衡量在你的情况下哪个版本更好。在我的例子中(一个数组有69个64位数字,另一个二维数组有48*12个字符),静态版本的速度要快得多。

你为什么认为这是一个优化?你是说“序列化”而不是“消毒”?@DavidSchwartz嗯,我不确定是不是,作者们似乎这么认为。我会这样假设,因为它不需要函数每次调用时都重建数组。另一方面,大多数现代编译器可能足够聪明,可以围绕这一点进行优化。这是一个静态声明。它不会在每次调用时重建,因此从本质上讲,似乎没有任何理由相信这是一种优化。我不确定“重建”阵列是什么意思。如果保存了一些工作,我看不到。因此,如果在函数中分配了数组,则可能不会影响性能?因为它是一个静态数组,所以不完全在函数中分配。所以不。。。不会影响性能的,很好。但是我尝试使用静态数组(您在两个函数中都使用了静态数组),因此实际的比较略有不同。您是如何获得这里的时间输出的?我使用UNIX
time
命令获得时间输出:谢谢,我只是自己尝试过(在trial2中没有声明数组是静态的)两次试验的结果都是一样的。你用了什么优化方法?我刚意识到这可能没有任何意义。哇。。。我没有遵循基准测试的第一条规则:启用所有优化。通过对源代码进行一些小的修改,我得到了几乎相同的结果。但那是-O0。有了-O3,静态版本的速度快了2个数量级。
./trial.out  57.32s user 0.04s system 97% cpu 58.810 total

./trial.out  57.77s user 0.04s system 97% cpu 59.259 total