如何加快加载文本文件到多向量
How to speed up loading text file to multi vector
我必须加载带有数据的大文件(几个GB(,我想将它们加载到二维向量。下面的代码可以完成这项工作,但它非常慢。更具体地说,目标是获取所有行,而第二列中的值等于索引(_lh,_sh(。然后排除第四列值与线 1和线路1相同的行。现在,我是C 的新手,我在Python中使用了常规代码(已经有此问题的工作代码(。但是我需要它的速度尽可能快,因此我试图将我的Python代码重写为C 。但是它比现在比Python慢(仅将数据传达给向量(...因此,在我继续之前,我想改进这一点。根据我在类似问题中发现的问题,问题将是动态向量,.push_back((和getline((。
我对类似问题中提到的映射和块加载感到困惑,因此我无法更改这些代码。
您能帮我优化此代码吗?
谢谢。
#include <iostream>
#include <sstream>
#include <fstream>
#include <array>
#include <string>
#include <vector>
using namespace std;
int pixel(int radek, int sloupec, int rozmer = 256) {
int index = (radek - 1) * rozmer + sloupec;
int index_lh = (index - rozmer - 1);
int index_sh = (index - rozmer);
int index_ph = (index - rozmer + 1);
int index_l = (index - 1);
int index_p = (index + 1);
int index_ld = (index + rozmer - 1);
int index_sd = (index + rozmer);
int index_pd = (index + rozmer + 1);
array<int, 9> index_all = { {index, index_lh, index_sh, index_ph, index_l, index_p, index_ld, index_sd, index_pd } };
vector<vector<string>> Data;
vector<string> Line;
string line;
for (int m = 2; m < 3; m++) {
string url = ("e:/TPX3 - kalibrace - 170420/ToT_ToA_calib_Zn_" + to_string(m) + string(".t3pa"));
cout << url << endl;
ifstream infile(url);
if (!infile)
{
cout << "Error opening output file" << endl;
system("pause");
return -1;
}
while (getline(infile, line))
{
Line.push_back(line);
istringstream txtStream(line);
string txtElement;
vector<string> Element;
while (getline(txtStream, txtElement, 't')){
Element.push_back(txtElement);
}
Data.push_back(Element);
}
}
cout << Data[1][0] << ' ' << Data[1][1] << ' ' << Data[1][2] << endl;
return 0;
}
int main()
{
int x = pixel(120, 120);
cout << x << endl;
system("pause");
return 0;
}
向量经常重新分配其基础缓冲区,可能会变得慢。需要在连续内存的缓冲区上实现向量,并且每次超过缓冲区限制时,它都必须分配一个新的和较大的缓冲区,然后将内容从旧缓冲区复制到新的缓冲区。如果您知道需要多大的缓冲区(不需要擦干(,则可以帮助程序分配适当尺寸的缓冲区,例如使用例如。Data.reserve(n)
(其中n
大约是您认为需要的元素数(。这确实注意到了矢量的"大小",只是基础缓冲区的大小。总之,我不得不说我从未真正对此进行基准测试,因此这可能会或可能不会改善您的程序的性能。
编辑:不过,我认为性能更有可能由Data.push_back(Element);
行瓶装,该行可以复制元素矢量。如果您使用的是C 11,我相信可以通过执行Data.emplace_back(std::move(Element));
之类的操作来解决此问题,在这种情况下,您将无法更改Element
(内容已移动(。您还需要为std::move
包含memory
。
在段循环中,您可以尝试从
更改行while (getline(infile, line))
{
Line.push_back(line);
istringstream txtStream(line);
string txtElement;
vector<string> Element;
while (getline(txtStream, txtElement, 't')){
Element.push_back(txtElement);
}
Data.push_back(Element);
}
to:
while (getline(infile, line))
{
Line.push_back(line);
istringstream txtStream(line);
string txtElement;
//vector<string> Element; [-]
Data.emplace_back(); // [+]
while (getline(txtStream, txtElement, 't')) {
//Element.push_back(txtElement); [-]
Data.back().push_back(txtElement); // [+]
}
//Data.push_back(Element); [-]
}
这样,Data
中的向量不需要在此处移动或复制 - 它们已经构造,尽管是空的。Data
中的向量使用.emplace_back()
默认构造。我们使用.back()
功能获得Data
中的最后一个元素,并像往常一样使用.push_back()
来推动我们的值。希望这会有所帮助:(
您可以尝试使用旧的C文件读取API(FILE*
,fopen()
等(或为std::istringstream
设置更大的缓冲区,如下所示
constexp std::size_t dimBuff { 10240 } // 10K, by example
char myBuff[dimBuff];
// ...
istringstream txtStream(line);
txtStream.rdbuf()->pubsetbuf(myBuff, dimBuff);
您可以尝试的另一件事是使用std::deque
S代替std::vector
S(但是我不知道这是否有用(。
MUOS建议,您可以使用移动语义;您也可以使用emplace_back()
。
所以我建议尝试
Element.push_back(std::move(txtElement));
Data.push_back(std::move(Element));
或
Element.emplace_back(std::move(txtElement));
Data.emplace_back(std::move(Element));
您也可以使用以下行(如果我没错的话,从std::istringstream
的字符串中没有移动构造函数(
Line.push_back(line);
istringstream txtStream(line);
添加移动语义(和emplace_back()
(
istringstream txtStream(line);
Line.emplace_back(std::move(line));
P.S。:显然reserve()
是有用的
您还可以在向量上使用reserve(int)
,以便它们更接近目标大小。
也可以避免在堆周围跳很多矢量,因为仅重新创建矢量会通过目标大小。
如果向量通过您先前保留的大小,则可以再次致电储备金:
vector<int> vec;
vec.reserve(10);
for (int i=0;i < 1000; i++)
{
if ( vec.size() == vec.capacity() )
{
vec.reserve(vec.size()+10);
}
vec.push_back(i);
}
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 如何在目录及其子文件夹中构建文件名字符串向量?
- 尝试将字符串从文件读取到无符号字符向量中
- 如何将包含另一个对象向量的对象保存到文件中,并使用C++中的二进制文件从文件中读回?
- 将结构向量保存到文件中,并从C++文件中读取结构向量
- C++,从文件读取到结构,然后读取到向量(结构被推入向量太多次,而不仅仅是一次)
- 从.txt文件读取到C++中的双精度向量
- 遍历对象向量,并找到与从文本文件中提取的对象匹配的变量
- C++ 将 CSV 文件的列写入向量
- 数组向量的文件 I/O
- 如何在C++中将.csv文件的元素存储到二维向量中?
- 包含换行符分隔的单词的文件和C++中这些单词的字符串向量的大小是否相同?
- C++文件中的向量
- 如何从输入文件中读取字符并将其存储到向量中?
- 如何从文件中为C++中的向量赋值?
- 将无符号字符的向量写入二进制文件 c++
- 通过将文本文件读取为字符串/向量来计算加权/未加权 GPA
- 如何将目录中的文件属性填充到结构向量中?
- 如何从文件中读取 n 个字节并使用<uint8_t>迭代器将它们放入向量中?
- 类对象的向量C++文件返回程序