#line #reader #ripgrep #greatest #world #iteration #contributors

ripline

这并不是世界上最好的行读取器,这只是一个致敬。快速基于行的迭代几乎完全来自 ripgrep 的 grep_searcher。所有荣誉归 Andrew Gallant 和 ripgrep 贡献者。

1 个不稳定版本

0.1.0 2021 年 7 月 3 日

#5#greatest

Download history 10/week @ 2024-03-16 14/week @ 2024-03-23 36/week @ 2024-03-30 14/week @ 2024-04-06 86/week @ 2024-04-13 15/week @ 2024-04-20 12/week @ 2024-04-27 11/week @ 2024-05-04 9/week @ 2024-05-11 7/week @ 2024-05-18 11/week @ 2024-05-25 16/week @ 2024-06-01 24/week @ 2024-06-08 29/week @ 2024-06-15 11/week @ 2024-06-22 1/week @ 2024-06-29

67 每月下载
用于 2 crates

Unlicense/MIT

52KB
808

🌊 ripline

Build Status license Version info
这并不是世界上最好的行读取器,这只是一个致敬。

快速基于行的迭代几乎完全来自 ripgrep 的 grep_searcher

所有荣誉归 Andrew Gallant 和 ripgrep 贡献者。

为什么?

  • 不依赖于闭包,如 bstr::for_line* 方法(在某些奖项生命周期场景中很有用)。
  • 没有像 rust-linereader 那样静默限制行长度
  • 为与 memmap 文件一起工作提供了 LineIter

并非所有这些功能都在 grep_searcher crate 中公开,这是正确的,因为其中许多功能都嵌入到逻辑中(例如二进制检测)。

我都做了什么改变?

没有太多改变。我移除了一些 ripgrep 特定的逻辑,例如二进制检测,一些搜索相关的配置,并合并了来自其他 grep_* crates 的几个辅助结构。

示例

更多示例请参阅 examples

use grep_cli::stdout;
use ripline::{
    line_buffer::{LineBufferBuilder, LineBufferReader},
    lines::LineIter,
    LineTerminator,
};
use std::{env, error::Error, fs::File, io::Write, path::PathBuf};
use termcolor::ColorChoice;

fn main() -> Result<(), Box<dyn Error>> {
    let path = PathBuf::from(env::args().nth(1).expect("Failed to provide input file"));

    let mut out = stdout(ColorChoice::Never);

    let reader = File::open(&path)?;
    let terminator = LineTerminator::byte(b'\n');
    let mut line_buffer = LineBufferBuilder::new().build();
    let mut lb_reader = LineBufferReader::new(reader, &mut line_buffer);

    while lb_reader.fill()? {
        let lines = LineIter::new(terminator.as_byte(), lb_reader.buffer());
        for line in lines {
            out.write_all(line)?;
        }
        lb_reader.consume_all();
    }

    Ok(())
}

粗略且不可靠的基准测试

来自 examples/ripline_benchmarks.rs。最初的基准脚本取自 rust-linereader,也包含在基准测试中,作为 LR:*

使用的输入是 all_train.csv,解压缩后可以连接五次,创建一个 ~25G 的文件。

方法 时间 每秒行数 带宽
read() 2.01 秒 17439155 行/秒 12303.42 MB/秒
LR::next_batch() 2.11 秒 16576174 行/秒 11694.59 MB/秒
LR::next_line() 2.65 秒 13196734 行/秒 9310.37 MB/秒
ripline_line_buffer() 2.64 秒 13277194 行/秒 9367.14 MB/秒
ripline_mmap() 2.16 秒 16183503 行/秒 11417.55 MB/秒
bstr_for_line() 2.47 秒 14174502 行/秒 10000.19 MB/秒
read_until() 2.86 秒 12230594 行/秒 8628.75 MB/秒
read_line() 4.16 秒 8417415 行/秒 5938.53 MB/秒
lines() 5.05 秒 6930901 行/秒 4889.79 MB/秒

请注意,readnext_batch不会计算行数。

硬件:Ubuntu 20 AMD Ryzen 9 3950X 16核处理器,64 GB DDR4内存和1TB NVMe驱动器

依赖项

~740KB
~11K SLoC