在性能方面,什么会更快?有什么不同吗?它依赖于平台吗?
//1. Using vector<string>::iterator:
vector<string> vs = GetVector();
for(vector<string>::iterator it = vs.begin(); it != vs.end(); ++it)
{
*it = "Am I faster?";
}
//2. Using size_t index:
for(size_t i = 0; i < vs.size(); ++i)
{
//One option:
vs.at(i) = "Am I faster?";
//Another option:
vs[i] = "Am I faster?";
}发布于 2009-04-22 10:57:41
使用迭代器会导致指针递增(用于递增)和取消引用为取消引用指针。
对于索引,增量应该同样快,但查找元素涉及加法(data pointer+index)和取消引用该指针,但差异应该是微不足道的。
at()还会检查索引是否在界限内,因此它可能会更慢。
500M迭代的基准测试结果,向量大小为10,使用gcc 4.3.3 (-O3),Linux2.6.29.1 x86_64:
at():9158ms
operator[]:4269ms
iterator:3914ms
YMMV,但是如果使用索引使代码更易读或更容易理解,您应该这样做。
2021年更新
在现代编译器中,所有选项实际上都是免费的,但迭代器在迭代方面稍好一些,并且更容易与范围循环(for(auto& x: vs))一起使用。
代码:
#include <vector>
void iter(std::vector<int> &vs) {
for(std::vector<int>::iterator it = vs.begin(); it != vs.end(); ++it)
*it = 5;
}
void index(std::vector<int> &vs) {
for(std::size_t i = 0; i < vs.size(); ++i)
vs[i] = 5;
}
void at(std::vector<int> &vs) {
for(std::size_t i = 0; i < vs.size(); ++i)
vs.at(i) = 5;
}为index()和at()生成的程序集是相同的godbolt,但iter()的循环设置少了两条指令:
iter(std::vector<int, std::allocator<int> >&):
mov rax, QWORD PTR [rdi]
mov rdx, QWORD PTR [rdi+8]
cmp rax, rdx
je .L1
.L3: ; loop body
mov DWORD PTR [rax], 5
add rax, 4
cmp rax, rdx
jne .L3
.L1:
ret
index(std::vector<int, std::allocator<int> >&):
mov rax, QWORD PTR [rdi]
mov rdx, QWORD PTR [rdi+8]
sub rdx, rax
mov rcx, rdx
shr rcx, 2
je .L6
add rdx, rax
.L8: ; loop body
mov DWORD PTR [rax], 5
add rax, 4
cmp rdx, rax
jne .L8
.L6:
ret发布于 2009-04-22 11:21:00
如果你不需要索引,就不要使用它。迭代器的概念是最好的。迭代器很容易优化,而直接访问则需要一些额外的知识。
索引是用于直接访问的。括号和at方法可以做到这一点。与[]不同的是,at会检查越界索引,因此速度会更慢。
信条是:不要索要你不需要的东西。这样编译器就不会为你不用的东西收费了。
发布于 2009-04-22 11:08:17
既然你关注的是效率,你应该意识到以下变化可能更有效:
//1. Using vector<string>::iterator:
vector<string> vs = GetVector();
for(vector<string>::iterator it = vs.begin(), end = vs.end(); it != end; ++it)
{
//...
}
//2. Using size_t index:
vector<string> vs = GetVector();
for(size_t i = 0, size = vs.size(); i != size; ++i)
{
//...
}因为end/size函数只调用一次,而不是通过循环每次都调用。编译器很可能无论如何都会内联这些函数,但这种方式可以确保。
https://stackoverflow.com/questions/776624
复制相似问题