Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中快速读取大文本文件到一维结构+;_C++_Performance_Io_Ifstream - Fatal编程技术网

C++ 在C+中快速读取大文本文件到一维结构+;

C++ 在C+中快速读取大文本文件到一维结构+;,c++,performance,io,ifstream,C++,Performance,Io,Ifstream,我需要快速读取一批大小高达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结构中,这样它就跳过了前两列。它基本上转

我需要快速读取一批大小高达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());
    }

}
void MyClass::GetFromFile(std::string filename,int headerLinestoSkip,int ColumnstoSkip,int numberofcolumnsined)
{
std::ifstream文件(文件名);
std::字符串文件\u行;
双温;
std::向量温度向量(numberofcolumnsined);
if(file.is_open())
{   
Skipline(文件、标题行或Skip);
while(getline(文件,文件行,'\n'))
{   
std::istringstream ss(文件行);
对于(int i=0;i>temp;
}
对于(int i=0;i>temp;
温度向量[i]。推回(温度);
}
}
对于(inti=0;iClassMemberVector.insert)(this->ClassMemberVector.end(),temp_向量[i].begin(),temp_向量[i].end());
}
}

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

如您所示,有20mb和短行,大约为500000行。知道这一点,有几个因素可能会降低代码的速度:

  • I/O:在目前的硬件和操作系统性能下,我无法想象这会在这里起作用
  • < LI>解析/转换。您读取每一行,从其中创建一个字符串流,然后提取数字。这可能是一个开销,特别是在一些流提取比旧代码< SCANFF()>代码>慢的C++实现中。我可能错了,但是我不确定这个开销会如此巨大。
  • 向量的内存分配。这绝对是第一个要查找的位置。向量有大小和容量。每次添加超过容量的项时,都需要重新分配向量,这可能需要移动并再次移动其所有内容
我强烈建议您使用探查器执行代码以识别瓶颈。手动计时在这里会很困难,因为您的循环包含所有潜在的问题,但每次迭代肯定会很快,以便以足够的精度测量不同的循环部分


如果您不能使用分析器,我建议您使用文件大小粗略估计行数,并取一半。然后计算每个
temp_向量[I]中的相应容量
。如果你观察到一个良好的进展,你将是正确的,然后可以微调这个方法。如果没有,用你的新发现编辑你的答案,并对这个答案发表评论。

由于你使用向量向量的方式,数据将不会按照你看起来想要的方式顺序排列。相反,数据将成为某种东西如
29 29…175 175 28 28 29…
等。使用调试器,逐行逐行检查代码,以了解原因。此外,您知道文件中将有多少行吗?您是否尝试过先检查行数的效果,然后为最终生成的向量保留空间并直接读取到其中?您顺序正确。我编辑以更正自己。所有文件中的行数可能不相同,因此我可能需要在我的类中使用它。您是否分析了
GetFromFile()
method查看它实际需要的时间在哪里?在同一个硬件上,当它运行时,它将运行在同一个硬件上?I/O:在当前的硬件和操作系统性能下,我无法想象这会在这里发挥作用;哦?!一个由好的硬件控制器连接的高端SSD RAID阵列不会比sin快几个数量级gle S-L-O-W 5400 RPM商品级SATA驱动器?@AndrewHenle别误会我:我完全同意硬件之间存在很大的幅度差异。但是-1)我假设OP认为它比他机器上的其他I/O操作慢-2)我们是在兆字节级别,因此,对于一个新版本,读取时间应该仍然太小,不会被视为瓶颈。