面向对象框架中成员函数返回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 带入循环似乎是显而易见的事情。或者,你能 运行 向后循环吗?
我在 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 带入循环似乎是显而易见的事情。或者,你能 运行 向后循环吗?