Doing `stdout.write_all(separator.as_bytes())?` is quite a bit
faster than using format to do the same operation:
`write!(stdout, "{separator}")?`.
This speeds up by about 10% on simple cases.
We do the same for the terminator even though this has no measurable
performance impact.
In most common use cases:
- We can bypass a lot of `write_output` when width == 0.
- Simplify format_float_decimal when the input is an integer.
Also document another interesting case in src/uu/seq/BENCHMARKING.md.
Display hexadecimal floats with arbitrary precision.
Note that some of the logic will produce extremely large
BitInt as intermediate values: there is some optimization
possible here, but the current implementation appears to work
fine for reasonable numbers (e.g. whatever would previously
fit in a f64, and even with somewhat large precision).
No more f64 operations needed, we just trim (or extend) BigDecimal to
appropriate precision, get the digits as a string, then add the
decimal point.
Similar to what BigDecimal::write_scientific_notation does, but
we need a little bit more control.
Using an associated type in Formatter trait was quite nice, but, in
a follow-up change, we'd like to pass a _reference_ to the Float
Formatter, while just passing i64/u64 as a value to the Int
formatters. Associated type doesn't allow for that, so we turn
it into a generic instead.
This makes Format<> a bit more complicated though, as we need
to specify both the Formatter, _and_ the type to be formatted.
Will make it possible to directly print ExtendedBigDecimal in `seq`,
and gradually get rid of limited f64 precision in other tools
(e.g. `printf`).
Changes are mostly mechanical, we reexport ExtendedBigDecimal directly
in format to keep the imports slightly shorter.
Issue #7494
Improve performace of wc app.
- Use the bytecount::num_chars API to count UTF-8 characters in a file.
- Enable runtime-dispatch-simd feature in the bytecount crate.
Use a BufWriter to wrap stdout: reduces the numbers of system calls,
improves performance drastically (2x in some cases).
Also document use cases in src/uu/seq/BENCHMARKING.md, and the
optimization we have just done here.
Fix issue #7372
Rework logic for handling all-but-last-lines and all-but-last-bytes
for non-seekable files. Changes give large performance improvement.
Commit 2a0d58d060 (part of https://github.com/uutils/coreutils/pull/3396 which contains a description of the changes) changed this line from libc::fsid_t to nix::sys::statfs::fsid_t.
The pull-request description at https://github.com/uutils/coreutils/pull/3396 indicates that this was done in order to fix the android build, and indeed using a cast to nix::sys::statfs::fsid_t
takes advantage of the definition of nix::sys::statfs::fsid_t which abstracts away the different name on Android:
```
/// Identifies a mounted file system
#[cfg(target_os = "android")]
pub type fsid_t = libc::__fsid_t;
/// Identifies a mounted file system
#[cfg(not(target_os = "android"))]
pub type fsid_t = libc::fsid_t;
```
This cast works as long as the libc version used by nix is the same than the libc version used by coreutils.
This cast becomes invalid when using a local libc version for local debugging, and changing Cargo.toml to point to it:
```
-libc = "0.2.153"
+libc = { path = "../path/to/libc" }
```
The cast becomes invalid because self.f_fsid is of type libc::fsid_t (local version of
libc), whereas nix::sys::statfs::fsid_t still uses the libc version downloaded
by cargo from crates.io in this case.
I was getting this error:
```
coreutils$ cargo build
Compiling libc v0.2.171 (/home/ecordonnier/dev/libc)
Compiling uucore v0.0.30 (/home/ecordonnier/dev/coreutils/src/uucore)
error[E0606]: casting `&libc::fsid_t` as `*const nix::libc::fsid_t` is invalid
--> src/uucore/src/lib/features/fsext.rs:816:25
|
816 | unsafe { &*(&self.f_fsid as *const nix::sys::statfs::fsid_t as *const [u32; 2]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0606`.
error: could not compile `uucore` (lib) due to 1 previous error
```
Let's rather use type inference to deal with libc::fsid_t vs libc::__fsid_t.
Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>
This removes the need for some manually duplicated code and keeps
shuf_exec() (which is generic) smaller, for less binary bloat and
better build times.
- shuf now uses OS strings, so it can read from filenames that are
invalid Unicode and it can shuffle arguments that are invalid
Unicode. `uucore` now has an `OsWrite` trait to support this without
platform-specific boilerplate.
- shuf no longer tries to split individual command line arguments,
only bulk input from a file/stdin. (This matches GNU and busybox.)
- More values are parsed inside clap instead of manually, leading to
better error messages and less code.
- Some code has been simplified or made more idiomatic.
0.0E+00 was not capitalized properly when using `%E` format.
Fixes#7382.
Test: cargo test --package uucore --all-features float
Test: cargo run printf "%E\n" 0 => 0.000000E+00
When using `touch -t` with a 2 digit year, the year is interpreted as
a relative year to 2000.
When the year is 68 or less, it should be interpreted as 20xx.
When the year is 69 or more, it should be interpreted as 19xx.
This is the behavior of GNU `touch`.
fixes gh-7280
Arguably 2 digits years should be deprecated as we
are already closer to 2069, than 1969.