Joë*_*ams 6 io performance rust
Rust 书提供了两个(此处相关)如何使用的示例BufRead。他们首先给出了一个“适合初学者”的例子,然后再介绍一个更“有效的方法”。
初学者友好的示例逐行读取文件:
use std::fs::File;
use std::io::{ self, BufRead, BufReader };
fn read_lines(filename: String) -> io::Lines<BufReader<File>> {
// Open the file in read-only mode.
let file = File::open(filename).unwrap();
// Read the file line by line, and return an iterator of the lines of the file.
return io::BufReader::new(file).lines();
}
fn main() {
// Stores the iterator of lines of the file in lines variable.
let lines = read_lines("./hosts".to_string());
// Iterate over the lines of the file, and in this case print them.
for line in lines {
println!("{}", line.unwrap());
}
}
Run Code Online (Sandbox Code Playgroud)
“有效方法”的作用几乎相同:
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
fn main() {
// File hosts must exist in current path before this produces output
if let Ok(lines) = read_lines("./hosts") {
// Consumes the iterator, returns an (Optional) String
for line in lines {
if let Ok(ip) = line {
println!("{}", ip);
}
}
}
}
// The output is wrapped in a Result to allow matching on errors
// Returns an Iterator to the Reader of the lines of the file.
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
Run Code Online (Sandbox Code Playgroud)
Rust 书中对后者的说法是:
此过程比在内存中创建字符串更有效,尤其是处理较大的文件时。
虽然后者稍微干净一些,但使用if let而不是unwrap,为什么返回 a 更有效Result?我假设一旦我们在第二个示例(在if let Ok(lines) = read_lines("./hosts"))中解开迭代器,从性能角度来看它应该与第一个示例相同。那为什么会有所不同呢?为什么第二个例子中的迭代器每次都会返回一个结果?
你是对的,“初学者友好”方法的效率并不低,并且不会“在内存中创建字符串”。看来我们很多人都感到困惑。
目前至少有两个拉取请求试图解决混乱,也许您可以对您喜欢的拉取请求发表评论:
这两个拉取请求都修改了初学者友好的方法来使用read_to_string而不是BufRead.
read_to_string使得初学者友好的方法“效率不高”,正如#1641 中的文本所暗示的那样。
read_to_string还给出了“在内存中创建一个String”的真实例子。有趣的是,自从第一次提交以来,“在内存中创建一个字符串”这句话就一直存在......
...起初,该短语仅描述了一种效率较低的假设方法...
...然后#1641以初学者友好的方法给出了一些实际代码...但效率丝毫不减!...
...直到 #1679 或 #1681 为止,从未有实际代码演示效率较低的方法!