std::vector 在 Linux 和 Windows 中给出不同的结果
std::vector gives different results in Linux and Windows
我的任务是分析 vector
在 Node
(由 long
值组成的对象)添加到它之前时的行为。
我在 Node
的复制构造函数中放置了一个计数器,以查看当向量移动到新位置时(即 vector
增长时它被调用了多少次。
我得到以下结果:
Windows - MinGW 编译器:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 411 411
Linux:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 227 227
Node.cpp
Node::Node(const Node& x){
this->value = x.get_value();
copy_count++;
}
SortedVector.cpp
vector<Node> data;
void SortedVector::prepend(const long value){
const Node x(value);
data.insert(data.begin(), x);
}
令人欣慰的是复制构造函数的计数与析构函数中的相同,但是你能帮我理解 Linux 和 Windows 中输出的区别吗?
不同之处在于它们是不同的实现。
你没有展示你的代码,所以我无法研究你使用的方法的实现差异,但我相信主要区别在于 std::vector
的实现。这完全取决于向量中插入的方式,特别是因为您存储的是 values 节点而不是指针。这意味着在必要时复制矢量内的对象没有任何异议。
对 insert
实现之间差异的可能猜测是,其中一个实现在需要增加容量时使用 realloc 来增加数组的大小,而另一个实现使用 malloc 然后复制所有新数组的值。如果重新分配的内存,在第一种情况下,只是增加大小的相同内存地址,则不需要副本。
P.S.: 为了将来参考,请在提出此类问题之前阅读 this page。重要的是要记住,当我们寻求帮助时,其他人并不像编写代码的人那样了解代码。
更新
要检查差异是否在于向量容量增加的方式,您可以在开始插入向量之前调用 std::vector::reserve
。在参数中使用 100
或更多参数调用它,以便向量具有您要插入的数字 Node
的容量。
您可能会发现此页面上的 table 很有用 useful。它列出了用于在各种编译器上扩展向量大小的几何比率。
您的结果不同是意料之中的事实。 memory allocation/memory fragmentation. Each has it's own strengths and weaknesses. My advice would be to trust the compiler writer to tune the vector to get the best out of the default allocation scheme, but if you need more control, manually manage the allocations with reserve and shrink to fit的问题有很多解决方法。
side-effecting 复制操作几乎不是一个好主意,但你的问题强调的是这是向量的要求。
我的任务是分析 vector
在 Node
(由 long
值组成的对象)添加到它之前时的行为。
我在 Node
的复制构造函数中放置了一个计数器,以查看当向量移动到新位置时(即 vector
增长时它被调用了多少次。
我得到以下结果:
Windows - MinGW 编译器:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 411 411
Linux:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 227 227
Node.cpp
Node::Node(const Node& x){
this->value = x.get_value();
copy_count++;
}
SortedVector.cpp
vector<Node> data;
void SortedVector::prepend(const long value){
const Node x(value);
data.insert(data.begin(), x);
}
令人欣慰的是复制构造函数的计数与析构函数中的相同,但是你能帮我理解 Linux 和 Windows 中输出的区别吗?
不同之处在于它们是不同的实现。
你没有展示你的代码,所以我无法研究你使用的方法的实现差异,但我相信主要区别在于 std::vector
的实现。这完全取决于向量中插入的方式,特别是因为您存储的是 values 节点而不是指针。这意味着在必要时复制矢量内的对象没有任何异议。
对 insert
实现之间差异的可能猜测是,其中一个实现在需要增加容量时使用 realloc 来增加数组的大小,而另一个实现使用 malloc 然后复制所有新数组的值。如果重新分配的内存,在第一种情况下,只是增加大小的相同内存地址,则不需要副本。
P.S.: 为了将来参考,请在提出此类问题之前阅读 this page。重要的是要记住,当我们寻求帮助时,其他人并不像编写代码的人那样了解代码。
更新
要检查差异是否在于向量容量增加的方式,您可以在开始插入向量之前调用 std::vector::reserve
。在参数中使用 100
或更多参数调用它,以便向量具有您要插入的数字 Node
的容量。
您可能会发现此页面上的 table 很有用 useful。它列出了用于在各种编译器上扩展向量大小的几何比率。
您的结果不同是意料之中的事实。 memory allocation/memory fragmentation. Each has it's own strengths and weaknesses. My advice would be to trust the compiler writer to tune the vector to get the best out of the default allocation scheme, but if you need more control, manually manage the allocations with reserve and shrink to fit的问题有很多解决方法。
side-effecting 复制操作几乎不是一个好主意,但你的问题强调的是这是向量的要求。