c++ - 为什么转置这个 std::vector<std::vector<std::string>> 这么慢?

标签 c++ string multidimensional-array transpose

我有一个 1000 行的文件,大约 400MB,代表一些用字符串表示的数字数据。 我想转置数据,以便每行只有 1000 个字符串(这样我就可以打开它并用 pandas 快速绘制它)。

我将整个文件导入到我想要转置的字符串 vector 中(最终我想写回文件)。

我使用两个嵌套循环遍历 2d 结构并将其写入某些 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 执行了分析。 在此过程中我收到此消息: ...线程 #1 中的 brk 段溢出:无法增长到 ...

我分析了结果并总结如下:
25% 花在了 basic_string 的 operator=
21% 用于构造 basic_string(只有 3% 的时间用于 new)
14% 花在外部 vector 的 operator()[] 上
11% 花在内部 vector 上的 operator()[]

感谢您的建议。

最佳答案

首先,在对一段代码运行缓慢的原因做出任何声明之前,您应该真正测量它在您机器上的性能,然后根据手头的数据推断原因

也就是说,在这种情况下我非常有信心地说,问题可能在于您正在分配 90k 个字符串 vector ,每个 vector 的大小为 1k .如您所知,内存分配成本很高,这可能会解释您的性能损失。

以下是如何仅使用预先分配的 1D 数组来实现您的代码。

size_t nbRows = mData.size();
size_t nbCols = mData[0].size();

auto get_idx = [](const int i, const int nr, const int j)
{
    return i*nr+j;
};

std::vector<std::string> transposedData(nbCols*nbRows);  
for(size_t i = 0 ; i < nbCols  ; ++i)
{
    for(size_t j = 0 ; j < nbRows ; ++j)
    {
        const int idx = get_idx(j, nbCols,i);
        transposedData[idx] = std::move(mData[j][i]);
    }
}

for(size_t i = 0 ; i < nbCols  ; ++i)
{
    for(size_t j = 0 ; j < nbRows ; ++j)
    {
        const int idx = get_idx(j, nbCols,i);
        cout<<transposedData[idx]<<" ";
    }
    cout<<endl;
}    

我想再次强调:分析你的代码。试用 valgrind --tool= callgrindgprof 等软件允许您分析和可视化有关您应用的性能数据。

关于c++ - 为什么转置这个 std::vector<std::vector<std::string>> 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58215449/

相关文章:

c++ - 为什么 QWizard::nextId() 被调用两次?

c++: 字符串常量的地址

javascript - 根据匹配键合并两个多维数组?

java - 在Java中对多维字符数组进行排序

c# - C#中字符串集合的排列

java - 在 Java 中为一个数字生成多个组合列表

C++ 模板专门化以提供/添加不同的成员函数

C++ boost - 是否有一个容器像队列一样工作,可以直接访问 key ?

c++ - 使用 Boost.Spirit 从 HTML 中提取某些标签/属性

python - 从单词列表中计算元音并将数字作为列表返回