想象一下以下声明:
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
}
如果有的话,这两者之间可能存在哪些性能差异?这些解决方案是否有任何危险?
这些解决方案是否有任何危险?
非静态是危险的,因为阵列很大,并且为自动存储保留的内存是有限的。根据系统和配置,该阵列可以使用大约30%的可用空间用于自动存储。因此,它大大增加了堆栈溢出的可能性。
虽然优化器肯定可以避免在堆栈上分配内存,但是有充分的理由说明为什么您希望非优化的调试版本也不会崩溃。
暂时忘掉阵列。这混淆了两个不同的问题。您有解决生命周期和存储问题的答案。我将解决初始化问题。
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++; }
如果有的话,这两者之间可能存在哪些性能差异?这些解决方案是否有任何危险?
差异完全取决于你如何使用foo()
。
第一种情况:(低概率):你的实现只会调用一次foo()
,也许你已经创建了单独的函数来划分代码逻辑。在这种情况下,声明为静态是非常糟糕的,因为静态变量或对象保留在内存中直到程序结束。所以想象一下你的变量不必要地占用了内存。
第二种情况:(高概率):你的实施是这样你将一次又一次地调用foo()
。然后一次又一次地分配和分配非静态对象。这将需要大量的cpu时钟周期,这是不希望的。在这种情况下使用静态。
在这个特定的上下文中,有一点要考虑在初始化变量上使用static
:
从C ++ 17标准:
6.7.1静态存储持续时间[basic.stc.static] ... 2如果具有静态存储持续时间的变量具有初始化或具有副作用的析构函数,则即使它看起来未被使用也不应被消除,除非可以按照15.8中的规定消除类对象或其复制/移动。