mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
tee: improve throughput by raw syscall - 17x perf win (#12131)
This commit is contained in:
@@ -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
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user