C++ 向量使结构排序变慢?c++;
我有一个按成员之一排序的结构列表。我使用std::sort和我自己的比较函数,这部分很好。但是,当我从以下位置更改结构时,我注意到(非常)大的性能差距:C++ 向量使结构排序变慢?c++;,c++,sorting,vector,struct,C++,Sorting,Vector,Struct,我有一个按成员之一排序的结构列表。我使用std::sort和我自己的比较函数,这部分很好。但是,当我从以下位置更改结构时,我注意到(非常)大的性能差距: struct square { float x; float y; float z; float scale; float angle; GLuint texture; }; 到 struct square { 浮动x; 浮动y; 浮动z; 浮标; 浮动角; 胶合结构; 向量颜色; };
struct square
{
float x;
float y;
float z;
float scale;
float angle;
GLuint texture;
};
到
struct square
{
浮动x;
浮动y;
浮动z;
浮标;
浮动角;
胶合结构;
向量颜色;
};
后来我使用了一种完全不同的方法,我意识到使用像这样的向量是一个坏主意(我知道数组的大小-rgb),但我想知道为什么我的性能会受到影响。我将z值与排序进行比较
这是我的排序函数和结构列表:
std::vector <square> square_list;
//Then add a bunch of squares
bool sort (square a,square b)
{
return a.z < b.z;
}
//Here is the sort that is slow
std::sort (square_list.begin(),square_list.end(),sort);
std::向量平方_列表;
//然后加上一堆方块
布尔排序(正方形a、正方形b)
{
返回a.z
我想知道这是否与重新排序结构列表有关,因为在第二种情况下,它们的大小要大得多
谢谢你的回复
bool sort (square a,square b)
这将每次复制结构,包括向量。向量的复制速度比普通数组慢。你应该改用这个
bool sort (const square& a, const square& b)
如果您使用的是C++11,则可以将向量替换为
std::array
,因为大小是恒定的。排序每次复制您的值,并且std::vector预先分配一组内存。复制时间更长是否尝试在向量中存储指针而不是整个结构
std::vector <square*> square_list;
//Then add a bunch of squares
bool sort (square* a,square* b)
{
return a->z < b->z;
}
//Here is the sort that is slow
std::sort (square_list.begin(),square_list.end(),sort);
std::向量平方_列表;
//然后加上一堆方块
布尔排序(正方形*a,正方形*b)
{
返回a->zz;
}
//这是那种慢的
排序(square\u list.begin(),square\u list.end(),排序);
除了将参数作为常量引用,还可以使用函子进行比较。这通常更快,因为函子更容易内联
std::vector <square> square_list;
//Then add a bunch of squares
struct sort
{
bool operator() (const square& a, const square& b) const {
return a.z < b.z;
}
}
std::sort (square_list.begin(),square_list.end(),sort);
std::向量平方_列表;
//然后加上一堆方块
结构排序
{
布尔运算符()(常数平方和a、常数平方和b)常数{
返回a.z
如果将排序函数更改为bool sort(square&a,square&b)
,性能差异是否仍然存在?如果为结构编写移动构造函数/赋值运算符,可能会更快。这样,为color
(结构外部)分配的内存不需要重新分配和复制,但指针只是从一个向量移动到另一个向量。至少应该快一点。@j_kubik我不同意。这意味着将结构移动到排序函数中会损坏原始结构。@NeilKirk@mikhail我不是说将对象移动到排序函数中,这将是毫无意义的-我甚至不知道这是如何工作的,更不用说更快了。移动操作符会使它更快,因为比较后会发生什么-结构在数组中移动(通常与另一个结构交换,但我们没有用于此的操作符,经过良好优化的移动也会这样做),所以数组最终会被排序。我假设c++11实现将使用移动语义来移动/交换std::sort
@NeilKirk中的元素。这与预分配无关。如果只使用引用,为什么要更改处理代码?那么它应该是const ptr。另一方面,vector
可以更快地移动array
,所以这两种方法都值得一试。@juanchopanza你总的来说是对的。然而,我认为从这个问题来看,数组大小只有3:)问题确实如你所指出的那样。非常感谢你的投入。还有,juanchopanza,为什么vector的移动速度更快?@Miick vector只能复制指向数据的指针,而数组必须复制其所有数据。这是因为数据是如何由两个数据结构存储的。+1此外,如果square
序列本身不必排序,并且仅使用一次性排序视图是使用要求,则临时排序指针床也可能是有益的。无论如何,如果您知道使用.reserve()
的平方
计数的上限,那么这也是相当可观的。与等效函数相比,函数内联并不容易或困难。因为函数不依赖于任何状态,所以我不会在这里使用函子。@Neil Kirk我不知道任何编译器可以通过函数指针内联函数调用
std::vector <square> square_list;
//Then add a bunch of squares
struct sort
{
bool operator() (const square& a, const square& b) const {
return a.z < b.z;
}
}
std::sort (square_list.begin(),square_list.end(),sort);