假设我们有两个功能:
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变为静态并仅初始化一次吗?
答案 0 :(得分:0)
为什么在不分析特定系统的情况下,我不能说(并且不相信其他声称的人)哪个更快,值得在两种情况下都考虑性能影响,假设常规优化。
在第二种情况下,将使用每个函数入口创建一个std::unordered_map
。我不知道有哪个优化器可以将这个自动变量转换为静态变量,而且我无法想象编译器甚至可能会发现它。主要的性能问题是内存分配(在多线程环境中非常重要,在单线程环境中要少得多)和使用三个元素初始化映射的成本-可能是,映射节点的另一种内存分配,以及字符串的内存分配,除非在目标平台上启用了SSO。
第一个版本不会遇到上述性能问题-第一次调用该功能时,它将仅执行一次所有必要的内存分配。
但是,它将受到其他因素的影响-自2011年以来,静态本地化的初始化是线程安全的,因此要检查隐藏的布尔值标志会产生成本。还有一个涉及内存同步的问题,但是由于任何理智的编译器都将在此处使用双重检查锁定,因此这些问题不相关。照原样,剩下的就是检查每个入口和分支上的布尔值。希望分支预测器很快就会投入使用并为我们做得很好,因此剩下的只是简单的比较成本,几乎没有什么。