将一个STL向量有效地分配给另一个STL矢量(WSL问题)
Efficient assignment of a STL vector to another STL vector (WSL Issue)
我有一个关于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的执行时间现在也非常相似)
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 将一个STL向量有效地分配给另一个STL矢量(WSL问题)
- 从给定的STL容器中提取带有给定谓词的元素到另一个容器
- 将值从STL矢量存储到另一个矢量
- 使用 STL std::merge() 将向量的两个部分合并到另一个向量中
- 如果键已经存在,为什么 stl map 会插入另一个值,而不仅仅是更改它
- 将一个类中的STL容器传递给另一个类
- 如何将 std::unique_ptr<> 从一个 STL 容器移动到另一个容器?
- 如何将stl向量的引用内容复制到另一个stl向量
- 使用STL的哈希列表-我可以将STL列表中的一个项指向另一个项吗?
- 当传递给函数时,如何正确地将一个字符数组的内容复制到另一个字符数组,而不使用STL
- 如何使用boost序列化轻松地序列化包含另一个自定义类的STL容器的自定义类
- 将STL算法传递给另一个函数
- 使用另一个stl向量重新排序stl向量
- 以一种漂亮的STL方式检查一个范围是否是另一个范围的子范围