面向对象框架中成员函数返回std::vector.size()的效率

Efficiency of member function returning std::vector.size() in object oriented framework

我在 prob.h 中声明了一个 class 因此:

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)(请参阅下面的编辑更新)即使是调试版本,使用选项 -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 的私有成员,其大小只能通过 public 成员函数 A.vec_of_A_s_size() 访问。因此,在 for 循环中必须发生额外的 indirection/redirection 层。该线程上的答案似乎表明编译器确实会优化循环不变量。但是在向量的大小不直接且 public 可用的情况下(如上),编译器能否可靠地保证循环不变优化?

(3)在其他关于此类问题的相关问题中,常见的答案似乎是对程序进行概要分析。如果以及当我进行分析时,我究竟应该寻找什么来验证这个特定的优化?这段代码是一个更大的数值分析代码的一部分,这绝对不是当前的瓶颈。然而,很高兴知道如何在分析器中验证这一点。如果这个问题 (3) 过于宽泛,我们深表歉意。我对分析比较陌生。但是分析器是否允许分析单个函数,比如上面包含 for 循环的函数?这样,我就可以确定瓶颈在哪里,因为它与此功能有关。


编辑更新:

关于 (1),使用上述编译器选项的调试版本优化循环不变量是不正确的。我错了。在更深入的挖掘中,事实证明该函数确实被调用了两次。

如果你的循环在向量上调用一个非常量方法,那么我几乎可以肯定地说所有赌注都没有了。

如果您只在向量上调用 const 方法,那么您可能希望进行优化,但由于标准不需要它们,您不能真的责怪编译器没有进行对您来说显而易见的优化,

鉴于您可以在 for 循环中声明多个变量,只要它们属于同一类型,将 sz 带入循环似乎是显而易见的事情。或者,你能 运行 向后循环吗?