函数局部静态变量:从性能角度看pros/cons
Function local static variables: pros/cons from performance point of view
函数局部静态变量有哪些pros/cons纯粹从性能的角度?
这是一个例子:
// version 1
void func(/*some arguments here*/)
{
int64_t x;
int32_t y = 0;
void * p = 0;
// do something here
}
// version 2
void func(/*some arguments here*/)
{
static int64_t x;
static int32_t y; y = 0;
static void * p; p = 0;
// do something here
}
哪个版本会更快?它会永远更快吗?什么情况下为了性能使用静态局部变量可能会搬起石头砸自己的脚?
非常感谢您的帮助!
这个问题太宽泛,无法一般性地回答。但是,我只想分享我在开发一些实际应用程序方面的经验。正如@Aconcagua 在评论中指出的那样,如果辅助(未返回)本地对象的初始化或使用成本很高,则使其 static
并重用它可能会导致显着的加速。这种情况发生在我们的案例中,尤其是辅助局部向量,其中重用避免了堆分配。比较
void f() {
std::vector<...> v;
... // at least one allocation required in each call when inserting elements
}
和
void f() {
static std::vector<...> v;
v.clear();
... // no allocation required if elements fit into capacity
}
这同样适用于(非小)字符串。当然,如果可以通过这种方式创建非常大的 vectors/strings,应该意识到这种方法可能会显着增加进程 RSS(映射到 RAM 的内存量)。
在多线程应用中,我们只是使用thread_local
而不是static
。
另一方面,对于小对象,基本上是基本类型(例如示例代码中的整数或指针),我敢说使它们 static
可能会导致更多的内存访问。使用 非静态变量 ,它们更有可能 仅映射到寄存器 。对于 静态变量 ,它们的值必须在函数调用之间保留,这很可能会导致它们 存储在内存中 。
函数局部静态变量有哪些pros/cons纯粹从性能的角度?
这是一个例子:
// version 1
void func(/*some arguments here*/)
{
int64_t x;
int32_t y = 0;
void * p = 0;
// do something here
}
// version 2
void func(/*some arguments here*/)
{
static int64_t x;
static int32_t y; y = 0;
static void * p; p = 0;
// do something here
}
哪个版本会更快?它会永远更快吗?什么情况下为了性能使用静态局部变量可能会搬起石头砸自己的脚?
非常感谢您的帮助!
这个问题太宽泛,无法一般性地回答。但是,我只想分享我在开发一些实际应用程序方面的经验。正如@Aconcagua 在评论中指出的那样,如果辅助(未返回)本地对象的初始化或使用成本很高,则使其 static
并重用它可能会导致显着的加速。这种情况发生在我们的案例中,尤其是辅助局部向量,其中重用避免了堆分配。比较
void f() {
std::vector<...> v;
... // at least one allocation required in each call when inserting elements
}
和
void f() {
static std::vector<...> v;
v.clear();
... // no allocation required if elements fit into capacity
}
这同样适用于(非小)字符串。当然,如果可以通过这种方式创建非常大的 vectors/strings,应该意识到这种方法可能会显着增加进程 RSS(映射到 RAM 的内存量)。
在多线程应用中,我们只是使用thread_local
而不是static
。
另一方面,对于小对象,基本上是基本类型(例如示例代码中的整数或指针),我敢说使它们 static
可能会导致更多的内存访问。使用 非静态变量 ,它们更有可能 仅映射到寄存器 。对于 静态变量 ,它们的值必须在函数调用之间保留,这很可能会导致它们 存储在内存中 。