【发布时间】:2020-02-01 13:19:58
【问题描述】:
我有一个大约 400MB 的 1000 行文件,它表示一些表示为字符串的数字数据。 我想转置数据,以便每行只有 1000 个字符串(这样我就可以打开它并用 pandas 快速绘制它)。
我将整个文件导入到我想转置的字符串向量中(最终我想写回文件)。
我使用两个嵌套循环来遍历二维结构,并将其写入一些 std::ofstream。它很长。 然后我试着把注意力集中在转置上,我写了以下代码:
//Read 400MB file, 90K strings per line and 1K lines, and store it into
std::vector<std::vector<std::string>> mData;
// ...
// IO the file and populate mData with raw data
// ...
//All rows have same number of string
size_t nbRows = mData.size();
size_t nbCols = mData[0].size();
std::vector<std::vector<std::string> > transposedData(nbCols);
for(size_t i = 0 ; i < nbCols ; ++i)
{
transposedData[i].resize(nbRows);
for(size_t j = 0 ; j < nbRows ; ++j)
{
transposedData[i][j] = doc.mData[j][i];
}
}
我认为几秒钟就足够了,但需要几分钟。 此外,我正在尝试使用不同的输入尺寸(对于相同的 400MB 文件大小,每行只有 3 行和更多的字符串),而且速度要快得多。
编辑 1
根据人们的建议,我使用 callgrind 进行了分析。 我在此过程中收到此消息: ... brk 线程 #1 中的段溢出:不能增长到 ...
我分析了结果,在这里总结一下:
25 % 用于基本字符串的 operator=
21 % 用于构建 basic_string(只有 3% 的时间用于新建)
14 % 用于外部向量的 operator()[]
11 % 用于内部向量的 operator()[]
感谢您的建议。
【问题讨论】:
-
您是否分析了代码?我很确定瓶颈是输入和输出。
-
字符串是长还是短?如果它们很长并且您不打算重用 mData,则可以移动字符串而不是复制它们。
-
在 Linux 上,您可以使用 callgrind 来分析代码
-
嗯,你的实际代码中有IO,对吧?您是否已经确认它不是大部分时间使用的 IO?
-
注意:看看这个问题:1D or 2D array, what's faster? 关于向量构造的向量以及为什么应该使用一维方法(预分配)。
标签: c++ string multidimensional-array transpose