将一个STL向量有效地分配给另一个STL矢量(WSL问题)

Efficient assignment of a STL vector to another STL vector (WSL Issue)

本文关键字:STL 另一个 矢量 WSL 分配 问题 向量 一个 有效地      更新时间:2023-10-16

我有一个关于STL矢量分配时间的问题。

上下文是:我正在将一个二进制文件读取到std::vector中,如下所示:

std::vector<float> read_file(const std::string &file_path) {
std::ifstream stream(file_path);
if (!stream.good()) {
std::cout << "Cannot open file located at: " << file_path << std::endl;
return std::vector<float>();
}
stream.seekg(0, std::ios_base::end);    
auto size = stream.tellg();
stream.seekg(0, std::ios_base::beg);
std::vector<float> values(size / sizeof(float));
stream.read((char*) &values[0], size);
stream.close();
return values;
}

我有128个二进制文件,每个文件都包含~2.500.000浮点值

最终,我将拥有128x个std::vector<float>矢量。然而,我希望它们存储在一个列表/向量(应该说是矩阵)中,该列表/向量会变成这样的数据结构:std::vector<std::vector<float>>

问题是:

示例1:此代码段的执行时间将~700ms

std::vector<float> data;
for (int i = 1; i <= 128; ++i) {
data = read_file(getFile(i));
}

示例2:但是,此代码段的执行时间将需要~2000ms:

std::vector<std::vector<float>> data(128);
for (auto i = 1; i <= 128; ++i) {
data[i-1] = read_file(getFile(i));
}

根据我的理解,如果右侧是vector&&,则分配将执行移动操作,如果右侧为const vector&,则分配执行复制操作。考虑到RVO,在返回类型中添加std::move是没有价值的,因此返回的值不会被复制,而是被移动。然而,两个例子中的赋值应该做相同的事情:将返回向量的地址(右侧)赋值给左侧的向量。

问题:根据我的理解(这可能是错误的),并考虑到这两个示例,如果示例1实例2都执行相同的操作(优化已激活),为什么执行时间会有如此大的差异。我能做些什么改进来减少第二个例子的时间吗?(我想使第二个例子尽可能有效)

谢谢。

这不是一个答案,这是一种试图理解时间差异的方法,但这太长了,不能作为备注给出

在第一种情况下,您总是重用内存中相同的块,执行过程中所需的大小是小

但在第二种解决方案中,你需要128倍的内存,这可能解释了时间的差异吗?如果执行时间是实时的(执行期间交换?),则强制执行

比较案例:

int main(int, char ** argv)
{
switch (*argv[1]) {
case '1':
{
// this is your first case
std::vector<float> data;
for (int i = 1; i <= 128; ++i) {
data = read_file(getFile(i));
}
}
break;
case '2':
{
// this is your seconde case
std::vector<std::vector<float>> data(128);
for (auto i = 1; i <= 128; ++i) {
data[i-1] = read_file(getFile(i));
}
}
break;
default:
{
// this is equivalent to your first case EXCEPT that needs 128 times more memory 
std::vector<std::vector<float> *> data(128);
for (auto i = 1; i <= 128; ++i) {
data[i-1] = new std::vector<float>();
*(data[i-1]) = read_file(getFile(i));
}
}
break;
}
return 0;
}

当你用参数3运行时,你会得到参数为1或2的时间吗?如果2和3相似,这意味着原因是需要更高的内存大小。

我发现的问题是WSL环境(使用CLion进行编译)的I/O性能较低。尽管我在问题中没有提到这一方面,但我必须在各种平台和系统上编译相同的程序,才能了解到底发生了什么。

设置另一个建筑环境解决了这个问题(示例1和2的执行时间现在也非常相似)

相关文章: