mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Merge pull request #7485 from drinkcat/seq-buffered
seq: Buffer writes to stdout
This commit is contained in:
commit
09f4e60e93
2 changed files with 35 additions and 4 deletions
|
@ -19,7 +19,38 @@ Finally, you can compare the performance of the two versions of `seq`
|
|||
by running, for example,
|
||||
|
||||
```shell
|
||||
hyperfine "seq 1000000" "target/release/seq 1000000"
|
||||
hyperfine -L seq seq,target/release/seq "{seq} 1000000"
|
||||
```
|
||||
|
||||
## Interesting test cases
|
||||
|
||||
Performance characteristics may vary a lot depending on the parameters,
|
||||
and if custom formatting is required. In particular, it does appear
|
||||
that the GNU implementation is heavily optimized for positive integer
|
||||
outputs (which is probably the most common use case for `seq`).
|
||||
|
||||
Specifying a format or fixed width will slow down the
|
||||
execution a lot (~15-20 times on GNU `seq`):
|
||||
```shell
|
||||
hyperfine -L seq seq,target/release/seq "{seq} -f%g 1000000"
|
||||
hyperfine -L seq seq,target/release/seq "{seq} -w 1000000"
|
||||
```
|
||||
|
||||
Floating point increments, or any negative bound, also degrades the
|
||||
performance (~10-15 times on GNU `seq`):
|
||||
```shell
|
||||
hyperfine -L seq seq,./target/release/seq "{seq} 0 0.000001 1"
|
||||
hyperfine -L seq seq,./target/release/seq "{seq} -100 1 1000000"
|
||||
```
|
||||
|
||||
## Optimizations
|
||||
|
||||
### Buffering stdout
|
||||
|
||||
The original `uutils` implementation of `seq` did unbuffered writes
|
||||
to stdout, causing a large number of system calls (and therefore a large amount
|
||||
of system time). Simply wrapping `stdout` in a `BufWriter` increased performance
|
||||
by about 2 times for a floating point increment test case, leading to similar
|
||||
performance compared with GNU `seq`.
|
||||
|
||||
[0]: https://github.com/sharkdp/hyperfine
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// file that was distributed with this source code.
|
||||
// spell-checker:ignore (ToDO) bigdecimal extendedbigdecimal numberparse hexadecimalfloat
|
||||
use std::ffi::OsString;
|
||||
use std::io::{stdout, ErrorKind, Write};
|
||||
use std::io::{stdout, BufWriter, ErrorKind, Write};
|
||||
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use num_traits::{ToPrimitive, Zero};
|
||||
|
@ -262,8 +262,8 @@ fn print_seq(
|
|||
padding: usize,
|
||||
format: Option<&Format<num_format::Float>>,
|
||||
) -> std::io::Result<()> {
|
||||
let stdout = stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
let stdout = stdout().lock();
|
||||
let mut stdout = BufWriter::new(stdout);
|
||||
let (first, increment, last) = range;
|
||||
let mut value = first;
|
||||
let padding = if pad {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue