迭代器性能 [英] Iterator Performance
问题描述
与直接使用指针相比,实现和使用迭代器会引入任何类型的性能损失吗?
Does implementing and using an iterator introduce any kind of performance penalty, in comparison to directly using a pointer?
(假设我们使用最高的编译器优化... )
(suppose we use the highest compiler optimization...)
代码来自 http: //www.cplusplus.com/reference/iterator/iterator/
// std::iterator example
#include <iostream> // std::cout
#include <iterator> // std::iterator, std::input_iterator_tag
class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
int* p;
public:
MyIterator(int* x) :p(x) {}
MyIterator(const MyIterator& mit) : p(mit.p) {}
MyIterator& operator++() {++p;return *this;}
MyIterator operator++(int) {MyIterator tmp(*this); operator++(); return tmp;}
bool operator==(const MyIterator& rhs) {return p==rhs.p;}
bool operator!=(const MyIterator& rhs) {return p!=rhs.p;}
int& operator*() {return *p;}
};
int main () {
int numbers[]={10,20,30,40,50};
MyIterator from(numbers);
MyIterator until(numbers+5);
for (MyIterator it=from; it!=until; it++)
std::cout << *it << ' ';
std::cout << '\n';
return 0;
}
推荐答案
实现和使用迭代器介绍任何类型的
性能惩罚,与直接使用指针相比?\
Does implementing and using an iterator introduce any kind of performance penalty, in comparison to directly using a pointer?\
这个问题有问题,因为它假设所有迭代器是内存中连续数组的迭代器。但是迭代器是对指针的泛化。它也可以是链接列表,哈希映射,红黑树等的迭代器。因此,在这种情况下,你不能真正比较基于连续数组的迭代器到更复杂的迭代器的性能类型,像树。
This question is problematic, as it assumes all iterators are iterators to contiguous array in memory. but an iterator is a generalization to a pointer. it may also be an iterator to a linked list, a hash map, a red-black tree, etc. so with this case, you can't really compare the performance of a contiguous-array-based iterator to an iterator of more complex types, like trees.
现在,让我以不同的方式问这个问题:
now, let me ask the question differently:
一个连续数组的迭代器引入任何种类的
性能惩罚,与直接使用指针相比。\
Does implementing and using an iterator to a contiguous array introduce any kind of performance penalty, in comparison to directly using a pointer?\
好吧,不是真的,编译器几乎剥离了大多数C ++类包装器,并优化汇编代码到使用C指针生成的相同程序集。
well, not really, the compiler pretty much strips most of C++ class wrappers and optimize the assembly code to the same assembly that was generated using a C-pointer.
相信我?这里是从您的代码生成的汇编代码,使用visual studio 2015 update 4,x64编译:
don't believe me? here is the generated assembly code from your code, compiled with visual studio 2015 update 4, x64:
int main() {
00007FF7A1D71000 mov qword ptr [rsp+8],rbx
00007FF7A1D71005 push rdi
00007FF7A1D71006 sub rsp,40h
00007FF7A1D7100A mov rax,qword ptr [__security_cookie (07FF7A1D75000h)]
00007FF7A1D71011 xor rax,rsp
00007FF7A1D71014 mov qword ptr [rsp+38h],rax
00007FF7A1D71019 movdqa xmm0,xmmword ptr [__xmm@000000280000001e000000140000000a (07FF7A1D732C0h)]
00007FF7A1D71021 lea rbx,[numbers]
00007FF7A1D71026 movdqu xmmword ptr [numbers],xmm0
00007FF7A1D7102C mov dword ptr [rsp+30h],32h
00007FF7A1D71034 mov edi,5
00007FF7A1D71039 nop dword ptr [rax]
00007FF7A1D71040 mov edx,dword ptr [rbx]
00007FF7A1D71042 mov rcx,qword ptr [__imp_std::cout (07FF7A1D73080h)]
00007FF7A1D71049 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7A1D73088h)]
00007FF7A1D7104F mov rcx,rax
00007FF7A1D71052 mov dl,20h
00007FF7A1D71054 call std::operator<<<std::char_traits<char> > (07FF7A1D71110h)
00007FF7A1D71059 lea rbx,[rbx+4]
00007FF7A1D7105D sub rdi,1
00007FF7A1D71061 jne main+40h (07FF7A1D71040h)
00007FF7A1D71063 mov rcx,qword ptr [__imp_std::cout (07FF7A1D73080h)]
00007FF7A1D7106A mov dl,0Ah
00007FF7A1D7106C call std::operator<<<std::char_traits<char> > (07FF7A1D71110h)
00007FF7A1D71071 xor eax,eax
}
使用c指针:
int main() {
int numbers[] = { 10,20,30,40,50 };
for (MyIterator it = numbers; it != numbers + 5; it++)
std::cout << *it << ' ';
std::cout << '\n';
return 0;
}
int main() {
00007FF6A72E1000 mov qword ptr [rsp+8],rbx
00007FF6A72E1005 push rdi
00007FF6A72E1006 sub rsp,40h
00007FF6A72E100A mov rax,qword ptr [__security_cookie (07FF6A72E5000h)]
00007FF6A72E1011 xor rax,rsp
00007FF6A72E1014 mov qword ptr [rsp+38h],rax
00007FF6A72E1019 movdqa xmm0,xmmword ptr [__xmm@000000280000001e000000140000000a (07FF6A72E32C0h)]
00007FF6A72E1021 lea rbx,[numbers]
00007FF6A72E1026 movdqu xmmword ptr [numbers],xmm0
00007FF6A72E102C mov dword ptr [rsp+30h],32h
00007FF6A72E1034 mov edi,5
00007FF6A72E1039 nop dword ptr [rax]
00007FF6A72E1040 mov edx,dword ptr [rbx]
00007FF6A72E1042 mov rcx,qword ptr [__imp_std::cout (07FF6A72E3080h)]
00007FF6A72E1049 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF6A72E3088h)]
00007FF6A72E104F mov rcx,rax
00007FF6A72E1052 mov dl,20h
00007FF6A72E1054 call std::operator<<<std::char_traits<char> > (07FF6A72E1110h)
00007FF6A72E1059 lea rbx,[rbx+4]
00007FF6A72E105D sub rdi,1
00007FF6A72E1061 jne main+40h (07FF6A72E1040h)
00007FF6A72E1063 mov rcx,qword ptr [__imp_std::cout (07FF6A72E3080h)]
00007FF6A72E106A mov dl,0Ah
00007FF6A72E106C call std::operator<<<std::char_traits<char> > (07FF6A72E1110h)
00007FF6A72E1071 xor eax,eax
}
这篇关于迭代器性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!