Skip to content

std::io::copy's splice(2) optimization does not use extended pipe on Linux #155859

Description

@oech3

View all comments

uutils/coreutils head -c has splice fast-path which is not using io::copy's internal splice and manually calling it with 1 MiB pipe size:

$ truncate -s 1PB /tmp/huge
$ head -c 1PB /tmp/huge|pv>/dev/null
^C.3GiB 0:00:01 [37.3GiB/s]

I removed cfg for Linux from
https://github.com/uutils/coreutils/blob/6b16cc9688fe998f5dc2786f53f22ceea709e318/src/uu/head/src/head.rs#L169-L177 and tried

fn print_n_bytes(input: impl Read, n: u64) -> io::Result<u64> {
    // Read the first `n` bytes from the `input` reader.
    let mut reader = input.take(n);

    // Write those bytes to `stdout`.
    let stdout = io::stdout();
    // larger pipe size should improve throughtput with splice
    let _ = rustix::pipe::fcntl_setpipe_size(&stdout, 1024*1024);
    let mut stdout = stdout.lock();

    let bytes_written = io::copy(&mut reader, &mut stdout).map_err(wrap_in_stdout_error)?;

Then I have

$ target/debug/head -c 1PB /tmp/huge|pv>/dev/null
^C21GiB 0:00:02 [2.10GiB/s]

I think std::io::copy should honor (or implicitly extend pipe size of target to 1 MiB).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchO-linuxOperating system: LinuxT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions