The*_* do 25 c++ optimization performance
根据效率编写循环的首选方法是什么:方式a)
/*here I'm hoping that compiler will optimize this
code and won't be calling size every time it iterates through this loop*/
for (unsigned i = firstString.size(); i < anotherString.size(), ++i)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
或者我应该这样做:方式b)
unsigned first = firstString.size();
unsigned second = anotherString.size();
Run Code Online (Sandbox Code Playgroud)
现在我可以写:
for (unsigned i = first; i < second, ++i)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
第二种方式在我看来更糟糕的选择有两个原因:范围污染和冗长,但它的优点是确保每个对象都会调用一次size().
期待您的回答.
kni*_*ttl 62
我通常把这段代码写成:
/* i and size are local to the loop */
for (size_t i = firstString.size(), size = anotherString.size(); i < size; ++i) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
这样我就不会污染父作用域并避免调用anotherString.size()
每个循环迭代.
这对迭代器特别有用:
for(some_generic_type<T>::forward_iterator it = collection.begin(), end = collection.end();
it != end; ++it) {
// do something with *it
}
Run Code Online (Sandbox Code Playgroud)
Ter*_*fey 17
通常,让编译器执行此操作.专注于您正在做的事情的算法复杂性而不是微优化.
但请注意,您的两个示例在语义上不相同 - 如果循环体改变第二个字符串的大小,则两个循环将不会迭代相同的次数.因此,编译器可能无法执行您正在讨论的特定优化.
In *_*ico 15
我会先使用第一个版本,因为它看起来更干净,更容易打字.然后,您可以对其进行分析,以查看是否需要进行更多优化.
但我非常怀疑第一个版本会导致显着的性能下降.如果容器实现size()
如下:
inline size_t size() const
{
return _internal_data_member_representing_size;
}
Run Code Online (Sandbox Code Playgroud)
然后编译器应该能够内联函数,省略函数调用.我的编译器对标准容器的实现都是这样做的.
优秀的编译器如何优化您的代码?完全没有,因为它不能确定是否size()
有任何副作用.如果size()
您的代码依赖于任何副作用,那么在可能的编译器优化之后它们现在就消失了.
从编译器的角度来看,这种优化实际上并不安全,您需要自己完成.自己动手并不意味着你需要引入另外两个局部变量.根据您的大小实现,它可能是O(1)操作.如果size也是内联声明的,那么你也可以省去函数调用,使调用与size()
本地成员访问一样好.
归档时间: |
|
查看次数: |
1521 次 |
最近记录: |