想象一下以下声明:
void foo(){
const std::array<int, 80000> arr = {/* a lot of different values*/};
//do stuff
}
第二个:
void foo(){
static const std::array<int, 80000> arr = {/* a lot of different values*/};
//do stuff
}
如果有的话,两者之间可能会有哪些性能差异?这些解决方案中是否有任何危险?
答案 0 :(得分:15)
暂时忘记该数组。这混淆了两个独立的问题。您已经得到解决寿命和存储问题的答案。我将解决初始化问题。
void f() {
static const int x = get_x();
// do something with x
}
void g() {
const int x = get_x();
// do something with x
}
这两者的区别在于,第一个只会在第一次调用get_x()
时才调用f()
; x
会在程序的其余部分保留该值。每次调用get_x()
时,第二个将调用g()
。
如果get_x()
在后续调用中返回不同的值,则很重要:
int current_x = 0;
int get_x() { return current_x++; }
答案 1 :(得分:12)
这些解决方案中是否有任何危险?
非静态是危险的,因为阵列很大,并且为自动存储保留的内存是有限的。根据系统和配置的不同,该阵列可能会使用大约30%的自动存储空间。因此,它大大增加了堆栈溢出的可能性。
尽管优化器肯定可以避免在堆栈上分配内存,但是有充分的理由使您希望未优化的调试版本也不会崩溃。
答案 2 :(得分:5)
这两者之间可能存在性能差异吗?这些解决方案是否存在任何危险?
区别完全取决于您使用foo()
的方式。
第一种情况:(低概率):您的实现是只调用一次foo()
,也许您已经创建了单独的函数来按惯例划分代码逻辑。在这种情况下,声明为static非常不好,因为静态变量或对象保留在内存中直到程序结束。因此,请想象您的变量不必要地占用了内存。
第二种情况:(高概率):您的实现方式是您将一次又一次调用foo()
。这样,非静态对象将被分配并一次又一次地释放。这将占用大量的CPU时钟周期,这是不希望的。在这种情况下,请使用static。
答案 3 :(得分:2)
在这种特定情况下,需要考虑在具有初始化的变量上使用static
:
根据C ++ 17标准:
6.7.1静态存储持续时间[basic.stc.static]
...
2如果静态存储持续时间为的变量已初始化或具有副作用的析构函数,则即使看起来未使用,也不得将其消除,除非可以按照15.8的规定删除类对象或其复制/移动。