我有一个prob.h
这样声明的类:
struct A_s{
int a, b;
}
class A_c{
private:
std::vector<A_s> vec_of_A_s;
public:
int vec_of_A_s_size() const{return static_cast<int>(vec_of_A_s.size());}
}
在A_c A;//A is an object of class A_c
我的实现文件的其他地方.cpp
,我有以下行:
for(int i = 0; i < A.vec_of_A_s_size(); i++) {...//do loop stuff}
我从我的程序设计中知道A.vec_of_A_s_size()
是循环不变的。但是,我真的想避免以下情况(这很麻烦):
int sz = A.vec_of_A_s_size();
for(int i = 0; i < sz; i++) {...//do loop stuff}
我能否充分且始终如一地依赖一个编译器,即启用了优化 (-O2) 的发布版本不会vec_of_A_s.size()
每次都进行评估?
这是我已经尝试过的问题:
(1)(请参阅下面的编辑更新)即使使用调试版本,使用 options -fPIC -fno-strict-aliasing -fexceptions -g -std=c++14
,查看反汇编程序输出,vec_of_A_s.size()
也只评估一次。但是,编译器会始终如一地可靠地进行这种优化吗?有任何已知的例外吗?我的怀疑和需要保证的部分原因源于下面的问题(2)。
(2)我查看了关于 SO:Performance issue for vector::size() in a loop的相关问题。那里的问题直接评估循环中向量的大小,如下所示:
for(int i = 0; i < vec_of_A_s.size(); i++) {...//do loop stuff}
就我而言,该向量不能直接访问。它是一个私有成员,A_c
它的大小只能通过公共成员函数访问A.vec_of_A_s_size()
。因此,在 for 循环中必须发生额外的间接/重定向层。该线程上的答案似乎表明编译器确实会优化循环不变量。但是在向量的大小不能直接和公开获得的情况下(如上),编译器会可靠地保证循环不变优化吗?
(3)在关于此类问题的其他相关问题中,一个常见的答案似乎是对程序进行剖析。如果以及当我进行分析时,我究竟应该寻找什么来验证这个特定的优化?该代码是更大的数值分析代码的一部分,这绝对不是当前的瓶颈。然而,很高兴知道如何在分析器中验证这一点。如果这个问题 (3) 太宽泛,我们深表歉意。我对分析比较陌生。但是分析器是否允许分析单个函数,比如包含上述for
循环的函数?这样,我可以确定与此功能有关的瓶颈在哪里。
编辑更新:
在 (1) 上,使用所述编译器选项的调试构建优化循环不变量是不正确的。我错了。在更深入的挖掘中,事实证明该函数确实被调用了两次。