在C++中将大型文本文件快速读取为一维结构

Fast read of large text file to 1D structure in C++

本文关键字:读取 一维 结构 文件 C++ 大型 文本      更新时间:2023-10-16

我需要快速读取一批大小高达 20mb 的文本文件。

文本文件的格式。数字需要采用双精度,因为其他文件可能具有 3 位小数点精度:

0 0 29 175 175 175 175 174 
0 1 29 175 175 175 175 174 
0 2 29 28 175 175 175 174 
0 3 29 28 175 175 175 174 
0 4 29 29 175 175 175 174
.
.
. 

我想将每行的最后六个数字存储到一个单一的 1D 结构中,这样它就可以跳过前两列。它基本上转置了每一列,并水平连接了每个转置的列:

29 29 29 29 29 175 175 28 28 29 175 175 175 175 175...

这是我的班级尝试这样做,对于我的目的来说太慢了。

void MyClass::GetFromFile(std::string filename, int headerLinestoSkip, int ColumnstoSkip, int numberOfColumnsIneed)
{
std::ifstream file(filename);   
std::string file_line;
double temp;
std::vector<std::vector<double>> temp_vector(numberOfColumnsIneed);
if(file.is_open())
{   
    SkipLines(file, headerLinestoSkip);
    while(getline(file, file_line, 'n'))
    {   
        std::istringstream ss(file_line);
        for(int i=0; i<ColumnstoSkip; i++)
        {
            ss >> temp;
        }
        for(int i=0; i<numberOfColumnsIneed; i++)
        {
            ss >> temp;
            temp_vector[i].push_back(temp);
        }
    }
    for(int i=0; i<numberOfColumnsIneed; i++)
    {
        this->ClassMemberVector.insert(this->ClassMemberVector.end(), temp_vector[i].begin(), temp_vector[i].end());
    }
}

我已经读到内存映射文件可能会有所帮助,但我尝试将其放入我需要的 1D 结构中并没有成功。某人的例子将不胜感激!

如您所显示的 20mb 和短行,大约是 500 000 行。 知道这一点后,有几个因素可能会减慢您的代码速度:

  • I/O :在当前的硬件和操作系统性能下,我无法想象这在这里发挥作用;
  • 解析/转换。您读取每一行,从中构建一个字符串流,然后提取数字。 这可能是开销,尤其是在流提取比旧sscanf()慢的某些C++实现上。 我可能是错的,但我再次不确定这个开销会如此巨大。
  • 矢量的内存分配。 这绝对是第一个要寻找的地方。 向量具有大小和容量。 每次添加超出容量的项目时,都需要重新分配矢量,这可能需要移动并再次移动其所有内容。

我强烈建议您使用探查器执行代码以识别瓶颈。 手动计时在这里会很困难,因为您的循环包含所有潜在问题,但每次迭代肯定会让 std::chrono 以足够的精度测量不同的循环部分。

如果您不能使用探查器,我建议您使用文件大小粗略估计行数,并将其减半。预先预留,然后在每个temp_vector[i]中保留相应的容量。 如果你观察到一个良好的进展,你将是正确的轨道,然后可以微调这种方法。如果没有,请使用您的新发现编辑您的答案并对此答案发表评论。