将一个 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 个浮点数 值。
最终我会得到 128 x std::vector<float>
个向量。但是我希望它们存储在一个 list/vector (矩阵应该说)中,它变成这个数据结构: std::vector<std::vector<float>>
.
问题是:
示例 1: 此代码片段的执行时间将花费 ~700ms:
std::vector<float> data;
for (int i = 1; i <= 128; ++i) {
data = read_file(getFile(i));
}
示例 2: 但是,此代码片段的执行时间将花费 ~2000 毫秒:
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
添加到 return 类型是没有价值的,因此值 returned 不会被复制而是被移动。然而,两个示例中的赋值应该做同样的事情:将 returned 向量(右侧)的地址分配给左侧的向量。
问题:根据我的理解(可能是错误的)并考虑到这两个例子,为什么[=39=之间的执行时间差异如此之大? ]Example1 和 Example2 如果两者执行相同的操作(优化已激活)。我可以做些什么来减少第二个例子的时间吗? (我想让第二个例子尽可能高效)
谢谢。
这不是一个答案,它是一种尝试理解时间差异的方法,但这太长了,无法作为备注给出
在第一种情况下,您总是在内存中重复使用相同的块,执行期间所需的大小很小
但是在第二个解决方案中你需要多 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 相似,则表示原因是需要更大的内存大小。
我发现的问题是 I/O 性能低下的 WSL 环境(我正在使用 CLion 进行编译)。尽管我在问题中没有提到这方面,但我不得不在各种平台和系统上编译相同的程序,以便了解到底发生了什么。
设置另一个构建环境解决了这个问题(示例 1 和 2 的执行时间现在也非常相似)
我对完成 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 个浮点数 值。
最终我会得到 128 x std::vector<float>
个向量。但是我希望它们存储在一个 list/vector (矩阵应该说)中,它变成这个数据结构: std::vector<std::vector<float>>
.
问题是:
示例 1: 此代码片段的执行时间将花费 ~700ms:
std::vector<float> data;
for (int i = 1; i <= 128; ++i) {
data = read_file(getFile(i));
}
示例 2: 但是,此代码片段的执行时间将花费 ~2000 毫秒:
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
添加到 return 类型是没有价值的,因此值 returned 不会被复制而是被移动。然而,两个示例中的赋值应该做同样的事情:将 returned 向量(右侧)的地址分配给左侧的向量。
问题:根据我的理解(可能是错误的)并考虑到这两个例子,为什么[=39=之间的执行时间差异如此之大? ]Example1 和 Example2 如果两者执行相同的操作(优化已激活)。我可以做些什么来减少第二个例子的时间吗? (我想让第二个例子尽可能高效)
谢谢。
这不是一个答案,它是一种尝试理解时间差异的方法,但这太长了,无法作为备注给出
在第一种情况下,您总是在内存中重复使用相同的块,执行期间所需的大小很小
但是在第二个解决方案中你需要多 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 相似,则表示原因是需要更大的内存大小。
我发现的问题是 I/O 性能低下的 WSL 环境(我正在使用 CLion 进行编译)。尽管我在问题中没有提到这方面,但我不得不在各种平台和系统上编译相同的程序,以便了解到底发生了什么。
设置另一个构建环境解决了这个问题(示例 1 和 2 的执行时间现在也非常相似)