我使用for循环遍历向量中的所有元素,我看到了流畅的代码:
std::vector<int> vi;
// ... assume the vector gets populated
for(int i : vi)
{
// do stuff with i
}
然而,从一个快速测试来看,它似乎每次都在将值从向量复制到i中(我尝试在for循环中修改i,而向量保持不变)。
我这样问的原因是,我实际上是用一个大型结构的向量来做的。
std::vector<MyStruct> myStructList;
for(MyStruct oneStruct : myStructList)
{
cout << oneStruct;
}
那么...考虑到内存复制的数量,这是一种糟糕的做事方式吗?使用传统索引更有效吗?
for(int i=0; i<myStructList.size(); i++)
{
cout << myStructList[i];
}
谢谢,
我在编译器资源管理器上进行了测试,发现即使使用gcc 10.3进行-O3
优化,复制实际上也可以完成。
以下是我的测试代码:
#include <iostream>
#include <vector>
using std::cout;
struct MyStruct {
int a[32];
};
std::ostream& operator<<(std::ostream& s, const MyStruct& m) {
for (int i = 0; i < 32; i++) s << m.a[i] << ' ';
return s;
}
std::vector<MyStruct> myStructList;
void test(void) {
for(MyStruct oneStruct : myStructList)
{
cout << oneStruct;
}
}
以下是部分结果:
test():
pushq %r13
pushq %r12
pushq %rbp
pushq %rbx
subq $152, %rsp
movq myStructList(%rip), %r12
movq myStructList+8(%rip), %r13
cmpq %r13, %r12
je .L8
leaq 144(%rsp), %rbp
.L11:
movdqu (%r12), %xmm0
movdqu 16(%r12), %xmm1
leaq 16(%rsp), %rbx
movdqu 32(%r12), %xmm2
movdqu 48(%r12), %xmm3
movdqu 64(%r12), %xmm4
movdqu 80(%r12), %xmm5
movups %xmm0, 16(%rsp)
movdqu 96(%r12), %xmm6
movdqu 112(%r12), %xmm7
movups %xmm1, 32(%rsp)
movups %xmm2, 48(%rsp)
movups %xmm3, 64(%rsp)
movups %xmm4, 80(%rsp)
movups %xmm5, 96(%rsp)
movups %xmm6, 112(%rsp)
movups %xmm7, 128(%rsp)
.L10:
movl (%rbx), %esi
movl $_ZSt4cout, %edi
addq $4, %rbx
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movl $1, %edx
leaq 15(%rsp), %rsi
movb $32, 15(%rsp)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
cmpq %rbp, %rbx
jne .L10
subq $-128, %r12
cmpq %r12, %r13
jne .L11
.L8:
addq $152, %rsp
popq %rbx
popq %rbp
popq %r12
popq %r13
ret
之间的行。L10:
和jne。L11对应于操作员
您应该添加
test():
pushq %r12
pushq %rbp
pushq %rbx
subq $16, %rsp
movq myStructList(%rip), %rbp
movq myStructList+8(%rip), %r12
cmpq %r12, %rbp
je .L8
subq $-128, %rbp
.L11:
leaq -128(%rbp), %rbx
.L10:
movl (%rbx), %esi
movl $_ZSt4cout, %edi
addq $4, %rbx
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movl $1, %edx
leaq 15(%rsp), %rsi
movb $32, 15(%rsp)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
cmpq %rbp, %rbx
jne .L10
leaq 128(%rbp), %rax
cmpq %rbp, %r12
je .L8
movq %rax, %rbp
jmp .L11
.L8:
addq $16, %rsp
popq %rbx
popq %rbp
popq %r12
ret
现在您可以看到,消除了大型复制,指向结构的指针直接用于执行
操作符
我有以下python生成器: 而且我想在Java中实现一个迭代器,它的行为有点像以前的生成器。我试图使用两个内部迭代器,但它不起作用。想法?
问题内容: 我想了解更多有关的信息,所以如果我错了,请纠正我。 迭代器是一个对象,该对象具有指向下一个对象的指针,并作为缓冲区或流(即,链表)读取。它们特别有效,因为它们所做的只是通过引用而不是使用索引来告诉您下一步是什么。 但是我仍然不明白为什么会发生以下行为: 经过迭代器()的第一个循环后,就好像它已被消耗并且留空,因此第二个循环()不输出任何内容。 但是,我从未为变量分配新值。 循环幕后到底
迭代器无效是如何处理的,而不是循环? 例如,这段代码不起作用,因为迭代器在插入后无效: 但是,如果我用这个for循环替换while循环,它会正确编译和运行: 为什么for循环有效而while循环无效?
问题内容: (对于那些熟悉JVM编译和优化技巧的人来说是一个问题… :-) 是否有任何一种“ for”和“ foreach”模式明显优于另一种? 考虑以下两个示例: 是快或慢? 假设在这两种情况下,阵列都不需要进行任何健全性检查,是否有明显的获胜者或仍然太接近而无法进行跟注? 编辑:正如在某些答案中指出的,数组的性能应该相同,而“ foreach”模式对于像列表这样的抽象数据类型可能会稍好一些。
当我开始我的代码 我得到无限循环。为什么?
问题内容: 这是我的代码: 增强的循环提供: 虽然此循环语句有效。为什么?代码有什么问题? 问题答案: 在这种情况下,将分配给数组中的每个元素-它 不是 数组的索引。 您想要做的是: 在您的代码中,您试图在迭代对象引用的数组索引处选择整数。换句话说,您的代码等效于: