为什么《Rust by Example》书中的BufRead高效示例高效?

问题描述 投票:0回答:1

《Rust by Examples》一书提供了两个(此处相关)示例,说明如何使用

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());
    }
}

“有效方法”的作用几乎相同:

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())
}

锈书对于后者的说法是:

此过程比在内存中创建字符串更有效,尤其是处理较大的文件时。

虽然后者稍微干净一些,但使用

if let
而不是
unwrap
,为什么返回
Result
效率更高呢? 我假设一旦我们在第二个示例中解开迭代器(在
if let Ok(lines) = read_lines("./hosts")
中),从性能角度来看它应该与第一个示例相同。 那为什么会有所不同呢? 为什么第二个例子中的迭代器每次都会返回一个结果?

performance rust io
1个回答
2
投票

你是对的“初学者友好”方法的效率并不低,并且不会“在内存中创建字符串”。看来我们很多人都感到困惑。

目前至少有两个拉取请求试图解决混乱,也许您可以评论您喜欢的拉取请求:

这两个拉取请求都修改了初学者友好的方法,以使用

read_to_string
而不是
BufRead

read_to_string
使得初学者友好的方法“效率不高”,正如#1641中的文本所暗示的那样

read_to_string
还给出了“在内存中创建String”的真实例子。有趣的是,自从第一次提交......

以来,“在内存中创建一个字符串”这句话就出现了。

...起初,该短语仅描述了一种假设的方法,效率较低...

...然后#1641以初学者友好的方法给出了一些实际代码...但是它效率丝毫不减!...

...直到 #1679 或 #1681 为止,从来没有 实际代码 展示了效率较低的方法!

更新 #1679 已合并到 master 中

© www.soinside.com 2019 - 2024. All rights reserved.