我对完成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 float 值。
最终,我将有 128 个x 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
添加到返回类型毫无意义,因此返回的值将不会被复制而是移动。但是,两个示例中的赋值都应该做相同的事情:将返回的矢量的地址(右侧)分配给左侧的矢量。
问题:根据我的理解(可能是错误的),并考虑到两个示例,为什么 Example1 与 Example1 之间的执行时间有如此大的差异 Example2 (如果两者执行相同的操作)(优化已激活)。我可以做些什么来减少第二个示例的时间? (我想使第二个示例尽可能高效)
谢谢。
答案 0 :(得分: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相似,则表示原因是所需的内存更大。
答案 1 :(得分:0)
我确定的问题是I / O性能低的WSL环境(使用CLion通过它进行编译)。即使我在问题中没有提及此方面,我也必须在各种平台和系统上编译相同的程序,以便了解发生了什么。
设置另一个建筑环境解决了该问题(示例1和示例2的执行时间现在也非常相似)