静态常量与常量局部变量,哪一个性能更好



假设我们有两个函数:

void foo_1(...)
{
static const unordered_map<int, string> m_1 = {{1, "abc"}, {2, "cde"}, {3, "fgh"}};
...
}
void foo_2(...)
{
const unordered_map<int, string> m_2 = {{1, "abc"}, {2, "cde"}, {3, "fgh"}};
...
}

哪一个会有更好的表现?编译器/优化器会理解它可以使m_2静态化并只初始化一次吗?

为什么我不能在不分析特定系统的情况下说(也不相信任何声称其他情况的人(哪一个更快,值得考虑这两种情况下的性能影响,假设是常规优化。

在第二种情况下,您将为每个函数入口创建一个std::unordered_map。据我所知,没有任何优化器可以将这个自动变量转换为静态变量,我甚至无法想象编译器是如何计算出来的。主要的性能影响将是内存分配(在多线程环境中非常重要,在单线程环境中更不重要(和用三个元素初始化映射的成本——可能是为映射节点分配另一个内存,可能是为字符串分配内存,除非在目标平台上启用SSO。

第一个版本不会出现上述性能问题——当第一次调用函数时,它将只执行一次所有必要的内存分配。

然而,它会受到其他因素的影响——因为自2011年以来,静态局部变量的初始化是线程安全的,所以检查隐藏的布尔标志会有成本。还有一个涉及内存同步的问题,但由于任何正常的编译器都会在这里使用双重检查锁定,因此这些问题不应该具有相关性。照原样,剩下的就是检查每个入口和分支上的布尔值。希望是,分支预测器很快就会发挥作用,并为我们做得很好,所以剩下的只是简单的比较成本,这几乎没有什么。

最新更新