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

文本文件采用以下格式。数字必须为 double 格式,因为某些其他文件的精度可能为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
.
.
.

我想将每行的最后六个数字存储到这样的单个一维结构中,以便跳过前两列。它基本上对每一列进行转置,并在水平方向上对每一转置列进行串联:
29 29 29 29 29 175 175 28 28 29 175 175 175 175 175...

这是我的类(class),尝试这样做对我而言太慢了。
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的短线,大约是50万条线。知道这一点,有几个因素可能会使您的代码变慢:

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

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

    如果您不能使用探查器,建议使用文件大小对行数进行粗略估算,然后取一半。 Pre-reserve然后每个temp_vector[i]中的相应容量。如果您观察到进展良好,那么您将走上正确的道路,然后可以微调此方法。如果不是,请使用新发现编辑您的答案,并对此答案发表评论。

    关于c++ - 在C++中将大型文本文件快速读取为一维结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38291544/

    10-16 15:13
    查看更多