英文:
Why is the efficient example of BufRead in the Rust book, efficient?
问题
以下是您要翻译的内容:
"The rust book gives two (relevant here) examples of how to use BufRead
. They first give a 'beginner friendly' example, before going onto a more 'Efficient method'.
The beginner friendly example reads a file line by line:
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());
}
}
The 'efficient method' does nearly the same:
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
fn main() {
// File hosts must exist in the 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())
}
The rust book states for the latter:
This process is more efficient than creating a String in memory, especially when working with larger files.
While the latter is slightly cleaner, using if let
instead of unwrap
, why is it more efficient to return a Result
? I assume that once we unwrap the iterator in the second example (in if let Ok(lines) = read_lines('./hosts')
), performance-wise it should be identical to the first example. Why does it differ then? Why does the iterator in the second example return a result each time?"
英文:
The rust book gives two (relevant here) examples of how to use BufRead
.
They first give a "beginner friendly" example, before going onto a more "Efficient method".
The beginner friendly example reads a file line by line:
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());
}
}
The "efficient method" does nearly the same:
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())
}
The rust book states for the latter:
> This process is more efficient than creating a String in memory especially working with larger files.
While the latter is slightly cleaner, using if let
instead of unwrap
, why is it more efficient to return a Result
?
I assume that once we unwrap the iterator in the second example (in if let Ok(lines) = read_lines("./hosts")
), that performance wise it should be identical to the first example.
Why does it differ then?
Why does the iterator in the second example return a result each time?
答案1
得分: 1
你说得对,"初学者友好" 的方法并不比较高效,并且不会在内存中"创建一个字符串"。看起来我们中的许多人都感到困惑。
目前至少有两个拉取请求试图解决这种困惑,也许你可以评论你偏好的拉取请求:
- https://github.com/rust-lang/rust-by-example/pull/1679
- https://github.com/rust-lang/rust-by-example/pull/1681
这两个拉取请求都修改了初学者友好的方法,使用read_to_string
而不是BufRead
。
read_to_string
使初学者友好的方法"不高效",正如#1641中的文本所建议的。
read_to_string
还提供了一个实际示例"在内存中创建一个字符串"。有趣的是,这个短语"在内存中创建一个字符串"自从第一个提交以来就一直存在...
...一开始这个短语只是描述了一个假设的方法,这种方法会不那么高效...
...然后#1641提供了一些初学者友好方法的实际代码... 但它并不比较高效!...
...直到#1679或#1681之前,从未有实际代码展示不那么高效的方法!
更新 #1679已合并到主分支。
英文:
You're right the "beginner friendly" method is no less efficient, and does not "create a String in memory". It seems like many of us were confused.
There are currently at least two pull requests which try to fix the confusion, maybe you can comment on the pull request you prefer:
- https://github.com/rust-lang/rust-by-example/pull/1679
- https://github.com/rust-lang/rust-by-example/pull/1681
Both of these pull requests modify the beginner friendly method to use read_to_string
instead of BufRead
.
read_to_string
makes the beginner friendly method "NOT efficient" as the text from #1641 suggests.
read_to_string
also gives a real example of "create a String in memory". It's funny the phrase "create a String in memory" was there since the very first commit....
...At first the phrase only described a hypothetical approach that would be less efficient ...
... then #1641 gave some actual code in a beginner-friendly method ... but it was no less efficient!...
...until #1679 or #1681 there was never actual code demonstrating the less efficient approach!
UPDATE #1679 was merged into master
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论