tee: improve throughput by raw syscall - 17x perf win (#12131)

This commit is contained in:
oech3
2026-05-15 11:44:08 +02:00
committed by GitHub
parent 645c1e3783
commit cb5a84e255
2 changed files with 25 additions and 22 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ doctest = false
[dependencies]
clap = { workspace = true }
rustix = { workspace = true, features = ["stdio", "fs"] }
uucore = { workspace = true, features = ["parser", "signals"] }
uucore = { workspace = true, features = ["fs", "parser", "signals"] }
fluent = { workspace = true }
[dev-dependencies]
+24 -21
View File
@@ -7,7 +7,7 @@
use std::ffi::OsString;
use std::fs::OpenOptions;
use std::io::{Error, ErrorKind, Read, Result, Write, stderr, stdin, stdout};
use std::io::{Error, ErrorKind, Read, Result, Write, stderr, stdin};
use std::path::PathBuf;
use uucore::display::Quotable;
use uucore::error::{UResult, strip_errno};
@@ -80,7 +80,10 @@ fn tee(options: &Options) -> Result<()> {
0,
NamedWriter {
name: translate!("tee-standard-output").into(),
inner: Writer::Stdout(stdout()),
#[cfg(any(unix, target_os = "wasi"))]
inner: Writer::Stdout(uucore::io::RawWriter(rustix::stdio::stdout())),
#[cfg(not(any(unix, target_os = "wasi")))]
inner: Writer::Stdout(std::io::stdout()),
},
);
@@ -197,12 +200,8 @@ impl MultiWriter {
fn write_flush(&mut self, buf: &[u8]) -> Result<()> {
let mode = self.output_error_mode;
self.writers.retain_mut(|writer| {
let res = (|| {
writer.inner.write_all(buf)?;
writer.inner.flush()
})();
match res {
self.writers
.retain_mut(|writer| match writer.inner.write_all(buf) {
Ok(()) => true,
Err(e) => {
if let Err(e) = process_error(mode, e, writer, &mut self.ignored_errors) {
@@ -210,8 +209,7 @@ impl MultiWriter {
}
false
}
}
});
});
self.aborted.take().map_or(
if self.writers.is_empty() {
// This error kind will never be raised by the standard
@@ -251,21 +249,26 @@ fn process_error(
enum Writer {
File(std::fs::File),
// remove buffering for posix requirement and improve throughput
#[cfg(any(unix, target_os = "wasi"))]
Stdout(uucore::io::RawWriter<rustix::fd::BorrowedFd<'static>>),
#[cfg(not(any(unix, target_os = "wasi")))]
Stdout(std::io::Stdout),
}
impl Write for Writer {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
impl Writer {
pub fn write_all(&mut self, buf: &[u8]) -> Result<()> {
match self {
Self::File(f) => f.write(buf),
Self::Stdout(s) => s.write(buf),
}
}
fn flush(&mut self) -> Result<()> {
match self {
Self::File(f) => f.flush(),
Self::Stdout(s) => s.flush(),
// File does not have line buffering
Self::File(f) => f.write_all(buf),
#[cfg(any(unix, target_os = "wasi"))]
Self::Stdout(s) => s.write_all(buf),
#[cfg(not(any(unix, target_os = "wasi")))]
Self::Stdout(s) => {
s.write_all(buf)?;
// needs unsafe to remove buffering... flush after write_all to keep overhead minimal
s.flush()
}
}
}
}