mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-04 23:17:46 +00:00
factors: Avoid repeatedly locking and flushing stdout
By default, stdout's LineWriter results one syscall per line, i.e. a billion syscalls when factoring a billion numbers... Buffering the output yields a ~28% speedup.
This commit is contained in:
parent
2869248318
commit
ef12991ee7
1 changed files with 22 additions and 16 deletions
|
@ -12,8 +12,9 @@ extern crate rand;
|
|||
extern crate uucore;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::io::{stdin, BufRead};
|
||||
use std::io::{self, stdin, stdout, BufRead, Write};
|
||||
use std::ops;
|
||||
|
||||
mod miller_rabin;
|
||||
|
@ -101,35 +102,40 @@ fn factor(mut n: u64) -> Factors {
|
|||
factors
|
||||
}
|
||||
|
||||
fn print_factors(num: u64) {
|
||||
print!("{}:{}", num, factor(num));
|
||||
println!();
|
||||
}
|
||||
|
||||
fn print_factors_str(num_str: &str) {
|
||||
if let Err(e) = num_str.parse::<u64>().and_then(|x| {
|
||||
print_factors(x);
|
||||
Ok(())
|
||||
}) {
|
||||
show_warning!("{}: {}", num_str, e);
|
||||
}
|
||||
fn print_factors_str(num_str: &str, w: &mut impl io::Write) -> Result<(), Box<dyn Error>> {
|
||||
num_str
|
||||
.parse::<u64>()
|
||||
.map_err(|e| e.into())
|
||||
.and_then(|x| writeln!(w, "{}:{}", x, factor(x)).map_err(|e| e.into()))
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let matches = app!(SYNTAX, SUMMARY, LONG_HELP).parse(args.collect_str());
|
||||
let stdout = stdout();
|
||||
let mut w = io::BufWriter::new(stdout.lock());
|
||||
|
||||
if matches.free.is_empty() {
|
||||
let stdin = stdin();
|
||||
|
||||
for line in stdin.lock().lines() {
|
||||
for number in line.unwrap().split_whitespace() {
|
||||
print_factors_str(number);
|
||||
if let Err(e) = print_factors_str(number, &mut w) {
|
||||
show_warning!("{}: {}", number, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for num_str in &matches.free {
|
||||
print_factors_str(num_str);
|
||||
for number in &matches.free {
|
||||
if let Err(e) = print_factors_str(number, &mut w) {
|
||||
show_warning!("{}: {}", number, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = w.flush() {
|
||||
show_error!("{}", e);
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue