令我惊讶的是,我注意到下面的 C++ 只是读取一个大文件行,将这些行存储到一个 vector 中并输出 vector 大小,它的运行速度比 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
python :
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;
}
这样你的内存将在你开始工作之前分配。
请注意 reserve
不是 resize
。
我的意思是 lines.reserve(10);
会提前分配 10 个 std::string
但 lines.empty()
仍然是 true。
如果无法预先知道行数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/