Performance std::vector的性能<;测试>;vs标准::向量<;测试*>;

Performance std::vector的性能<;测试>;vs标准::向量<;测试*>;,performance,pointers,stl,vector,stdvector,Performance,Pointers,Stl,Vector,Stdvector,在非POD数据类型的std::vector中,对象向量和指向对象的(智能)指针向量之间是否存在差异?我指的是编译器在实现这些数据结构时的差异 例如: 类测试{ std::字符串s; 测试*其他; }; std::向量vt; std::载体vpt; vt和vpt之间是否没有性能差异 换句话说:当我定义一个向量时,编译器会在内部创建一个向量吗?通常,无论向量中存储的类型是什么,都可以复制该向量的实例。这意味着,如果存储的是std::string,则将复制std::string的实例 例如,将类型推

在非POD数据类型的std::vector中,对象向量和指向对象的(智能)指针向量之间是否存在差异?我指的是编译器在实现这些数据结构时的差异

例如:

类测试{
std::字符串s;
测试*其他;
};
std::向量vt;
std::载体vpt;
vt和vpt之间是否没有性能差异


换句话说:当我定义一个
向量时,编译器会在内部创建一个
向量吗?

通常,无论向量中存储的类型是什么,都可以复制该向量的实例。这意味着,如果存储的是std::string,则将复制std::string的实例

例如,将类型推入向量时,类型实例将复制到向量内部的实例中。指针的复制将是便宜的,但是,正如Konrad Rudolph在评论中指出的,这不应该是你唯一考虑的事情。 对于像您的
测试
这样的简单对象,复制的速度将非常快,根本不重要

此外,在C++11中,移动允许避免在不必要时创建额外副本

简而言之:指针的复制速度会更快,但复制并不是唯一重要的事情。我会首先担心可维护的逻辑代码,以及当它成为问题(或情况需要它)时的性能


至于您关于内部指针向量的问题,不,向量被实现为数组,在必要时定期调整大小。您可以在网上找到GNU的矢量的libc++实现


答案比C++级别要复杂得多。由于整个程序无法装入寄存器,因此当然必须涉及指针。不过,我对这一级别的了解还不够详细。

一般来说,无论向量中存储的类型是什么,都可以复制它的实例。这意味着,如果存储的是std::string,则将复制std::string的实例

例如,将类型推入向量时,类型实例将复制到向量内部的实例中。指针的复制将是便宜的,但是,正如Konrad Rudolph在评论中指出的,这不应该是你唯一考虑的事情。 对于像您的
测试
这样的简单对象,复制的速度将非常快,根本不重要

此外,在C++11中,移动允许避免在不必要时创建额外副本

简而言之:指针的复制速度会更快,但复制并不是唯一重要的事情。我会首先担心可维护的逻辑代码,以及当它成为问题(或情况需要它)时的性能


至于您关于内部指针向量的问题,不,向量被实现为数组,在必要时定期调整大小。您可以在网上找到GNU的矢量的libc++实现

答案比C++级别要复杂得多。由于整个程序无法装入寄存器,因此当然必须涉及指针。不过,我对这一低水平的了解还不够详细

换句话说:当我定义一个向量时,编译器会在内部创建一个向量吗

不,这是C++标准不允许的。以下代码是合法的C++:

vector<Test> vt;
Test t1; t1.s = "1"; t1.other = NULL;
Test t2; t2.s = "1"; t2.other = NULL;
vt.push_back(t1);
vt.push_back(t2);
Test* pt = &vt[0];
pt++;
Test q = *pt; // q now equal to Test(2)
vectorvt;
测试t1;t1.s=“1”;t1.other=NULL;
测试t2;t2.s=“1”;t2.other=NULL;
vt.向后推(t1);
vt.向后推(t2);
测试*pt=&vt[0];
pt++;
测试q=*pt;//q现在等于测试(2)
换句话说,向量“衰减”为数组(像C数组一样访问它是合法的),因此编译器实际上必须将元素作为数组在内部存储,而不仅仅是存储指针

但是要注意,数组指针只有在向量没有重新分配的情况下才有效(通常只有当大小超过容量时才会发生这种情况)

换句话说:当我定义一个向量时,编译器会在内部创建一个向量吗

不,这是C++标准不允许的。以下代码是合法的C++:

vector<Test> vt;
Test t1; t1.s = "1"; t1.other = NULL;
Test t2; t2.s = "1"; t2.other = NULL;
vt.push_back(t1);
vt.push_back(t2);
Test* pt = &vt[0];
pt++;
Test q = *pt; // q now equal to Test(2)
vectorvt;
测试t1;t1.s=“1”;t1.other=NULL;
测试t2;t2.s=“1”;t2.other=NULL;
vt.向后推(t1);
vt.向后推(t2);
测试*pt=&vt[0];
pt++;
测试q=*pt;//q现在等于测试(2)
换句话说,向量“衰减”为数组(像C数组一样访问它是合法的),因此编译器实际上必须将元素作为数组在内部存储,而不仅仅是存储指针


但是要注意,数组指针只有在向量没有重新分配的情况下才有效(通常只有当大小超出容量时才会发生这种情况)。

这听起来好像使用指针更快。我认为,至少对于许多常见的使用模式,情况正好相反:由于增加了间接寻址和内存管理开销,使用指针的速度较慢。C++11移动赋值使这一点更加正确,但即使在C++03中也是如此。我编辑了我的问题。也许最后一行澄清了我的疑惑。@Pietro已经更新了我的答案来解决这个问题,希望能被澄清。Konrad Rudolph,你能解释一下为什么指针会变慢吗?如果列表为list dosnt,则需要创建新的测试实例,并在调用push_back时复制该值?谢谢这听起来好像使用指针更快。我认为,至少对于许多常见的使用模式,情况正好相反:由于增加了间接寻址和内存管理开销,使用指针的速度较慢。C++11移动赋值使这一点更加正确,但即使在C++03中也是如此。我编辑了我的问题。也许最后一行澄清了我的疑惑。@Pietro已经更新了我的答案来解决这个问题,希望能被澄清。Konrad Rudolph,你能解释一下为什么指针会变慢吗?如果