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

时间:2019-01-12 11:03:59

标签: c++ vector clion windows-subsystem-for-linux

我对完成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 (如果两者执行相同的操作)(优化已激活)。我可以做些什么来减少第二个示例的时间? (我想使第二个示例尽可能高效)

谢谢。

2 个答案:

答案 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的执行时间现在也非常相似)