Skip to content

Commit 21ab5f6

Browse files
committed
shuf: Tune performance for -i 1-1000000
1 parent e1259d9 commit 21ab5f6

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/uu/shuf/src/shuf.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ impl Writable for &OsStr {
378378
}
379379

380380
impl Writable for u64 {
381+
#[inline]
381382
fn write_all_to(&self, output: &mut impl OsWrite) -> Result<(), Error> {
382383
// The itoa crate is surprisingly much more efficient than a formatted write.
383384
// It speeds up `shuf -r -n1000000 -i1-1024` by 1.8×.
@@ -386,13 +387,23 @@ impl Writable for u64 {
386387
}
387388
}
388389

390+
#[cold]
391+
#[inline(never)]
392+
fn handle_write_error(e: std::io::Error) -> Box<dyn uucore::error::UError> {
393+
use uucore::error::FromIo;
394+
let ctx = translate!("shuf-error-write-failed");
395+
e.map_err_context(move || ctx)
396+
}
397+
398+
#[inline(never)]
389399
fn shuf_exec(
390400
input: &mut impl Shufable,
391401
opts: &Options,
392402
rng: &mut WrappedRng,
393403
output: &mut BufWriter<Box<dyn OsWrite>>,
394404
) -> UResult<()> {
395405
let ctx = || translate!("shuf-error-write-failed");
406+
let sep = [opts.sep];
396407
if opts.repeat {
397408
if input.is_empty() {
398409
return Err(USimpleError::new(
@@ -402,17 +413,21 @@ fn shuf_exec(
402413
}
403414
for _ in 0..opts.head_count {
404415
let r = input.choose(rng)?;
405-
406-
r.write_all_to(output).map_err_context(ctx)?;
407-
output.write_all(&[opts.sep]).map_err_context(ctx)?;
416+
if let Err(e) = r.write_all_to(output) {
417+
return Err(handle_write_error(e));
418+
}
419+
if let Err(e) = output.write_all(&sep) {
420+
return Err(handle_write_error(e));
421+
}
408422
}
409423
} else {
410424
let shuffled = input.partial_shuffle(rng, opts.head_count)?;
425+
let sep = [opts.sep];
411426

412427
for r in shuffled {
413428
let r = r?;
414-
r.write_all_to(output).map_err_context(ctx)?;
415-
output.write_all(&[opts.sep]).map_err_context(ctx)?;
429+
r.write_all_to(output).map_err(handle_write_error)?;
430+
output.write_all(&sep).map_err(handle_write_error)?;
416431
}
417432
}
418433
output.flush().map_err_context(ctx)?;

0 commit comments

Comments
 (0)