令我惊讶的是,我注意到下面的C ++仅读取一个大文件行,将这些行存储到一个向量中,然后输出向量大小,其运行速度比Python慢​​。如何优化呢?谢谢

#include <fstream>
#include <iostream>
#include <vector>
#include <string>

   int main () {
    std::ifstream infile("longfile.txt");
    std::string line;
    std::vector<std::string> lines;

    while (std::getline(infile, line)) {
        lines.push_back(line);
    }

    std::cout << lines.size() << std::endl;

    return 0;
}


跑:

$ time ./a.out
1390000

real    0m6.388s
user    0m6.130s
sys 0m0.243s


蟒蛇:

with open('longfile.txt') as f:
    lines = f.readlines()

print len(lines)


跑:

$ time python test.py
1390000

real    0m1.003s
user    0m0.158s
sys     0m0.146s

最佳答案

如果您可以事先知道必须阅读的行数,则可以保留std::vector对象中的行数。
假设您有10行要阅读:

   int main () {
    std::ifstream infile("longfile.txt");
    std::string line;
    std::vector<std::string> lines;

    lines.reserve(10);

    while (std::getline(infile, line)) {
        lines.push_back(line);
    }

    std::cout << lines.size() << std::endl;

    return 0;
}


这样,您的内存将在开始工作之前分配。
Becarefull reserve不是resize
我的意思是lines.reserve(10);将预先分配10个std::string,但lines.empty()仍然是正确的。

如果您不知道提前的行数std::list(双链接列表)或std::forward_list(简单链接列表)将很有帮助。
每个新元素都将添加到列表中,直到您完成读取文件为止。
在列表中,无需重新分配内存,每次达到最大容量时必须使用std::vector进行操作。
就时间而言,重新分配和复制内存中的元素非常昂贵。
使用列表,您至少可以减少文件解析期间所花费的时间。

将文件复制到std::vector后,解析文件是一个好主意,因为您已经知道需要连续内存分配的内存大小可以更快地进行访问。

无论您选择什么,我都强烈建议更改:

while (std::getline(infile, line)) {
    lines.push_back(line);
}


创建人:

    while (std::getline(infile, line)) {
        lines.push_back(std::move(line));
    }


默认情况下,对于STL中的大多数容器,复制构造函数或赋值运算符的调用将对数据进行完全复制。
std::move防止此类复制。

您可以使用以下示例轻松检查它:

std::string a("Hello");
std::string b(a);

std::cout<<a.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<a.c_str()<<" "<<b.c_str()<<std::endl;

std::string d(std::move(a));

std::cout<<a.size()<<" "<<d.size()<<std::endl;

std::string e;
std::string f;

e = b;

std::cout<<e.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<e.c_str()<<" "<<b.c_str()<<std::endl;


f = std::move(b);

std::cout<<f.size()<<" "<<b.size()<<std::endl;

关于python - 如何优化C++将文件逐行读入 vector ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35633017/

10-09 19:34
查看更多