From 79949ff8d823dcc959f82c696f7e285433383fdc Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Tue, 24 Aug 2021 16:50:08 -0500 Subject: [PATCH] use structopt instead of clap directly --- BENCHMARKING.md | 14 ++++++++++ Cargo.lock | 71 ++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 +- src/main.rs | 30 +++++++++------------ 4 files changed, 98 insertions(+), 19 deletions(-) diff --git a/BENCHMARKING.md b/BENCHMARKING.md index ca32ba1..6b8212b 100644 --- a/BENCHMARKING.md +++ b/BENCHMARKING.md @@ -71,3 +71,17 @@ Benchmark #1: ./target/release/similar-sort benchmark < /usr/share/dict/words ``` So, no to that too! + +## Removing arg parsing overhead? + +What if it's creating that big Clap struct that's causing problems? +Let's give structopt a try (and then move to deriving from Clap once 3.0.0 is finally released.) + +``` +$ hyperfine './target/release/similar-sort benchmark < /usr/share/dict/words' +Benchmark #1: ./target/release/similar-sort benchmark < /usr/share/dict/words + Time (mean ± σ): 667.5 ms ± 7.1 ms [User: 4.158 s, System: 0.031 s] + Range (min … max): 658.3 ms … 678.2 ms 10 runs +``` + +Ok, seems fine! diff --git a/Cargo.lock b/Cargo.lock index 194fc34..13b4edb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,6 +182,15 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -271,6 +280,30 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.28" @@ -339,10 +372,10 @@ dependencies = [ name = "similar-sort" version = "2.0.0" dependencies = [ - "clap", "color-eyre", "rayon", "strsim 0.10.0", + "structopt", ] [[package]] @@ -357,6 +390,30 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "structopt" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" version = "1.0.75" @@ -439,6 +496,12 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + [[package]] name = "unicode-width" version = "0.1.8" @@ -457,6 +520,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index d1758e9..d91660b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = "2.33.3" +structopt = "0.3.22" color-eyre = "0.5.7" rayon = "1.5.1" strsim = "0.10.0" diff --git a/src/main.rs b/src/main.rs index 4bd7e02..024d4ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,17 @@ -use clap::{crate_authors, crate_version, App, Arg}; -use color_eyre::eyre::{ContextCompat, Result, WrapErr}; +use color_eyre::eyre::{Result, WrapErr}; use rayon::prelude::*; use std::io::{self, stdin, stdout, BufRead, BufWriter, Write}; use strsim::levenshtein; +use structopt::StructOpt; + +// works like `sort`, but sorts according to Levenshtein distance instead of +// alphanumerically. +#[derive(StructOpt)] +#[structopt(name = "similar-sort")] +struct Opts { + /// sort according to distance from this string + target: String, +} fn main() { if let Err(err) = try_main() { @@ -14,20 +23,7 @@ fn main() { fn try_main() -> Result<()> { color_eyre::install()?; - let matches = App::new("similar-sort") - .version(crate_version!()) - .author(crate_authors!()) - .about("works like `sort`, but sorts according to Levenshtein distance instead of alphanumerically") - .arg( - Arg::with_name("target") - .value_name("TARGET") - .help("sort according to distance from this string") - .required(true) - ).get_matches(); - - let target = matches.value_of("target").context( - "could not get the target value. This is an internal error and should be reported.", - )?; + let opts = Opts::from_args(); let mut lines: Vec = stdin() .lock() @@ -35,7 +31,7 @@ fn try_main() -> Result<()> { .collect::>>() .context("could not read lines from stdin")?; - lines.par_sort_by_key(|candidate| levenshtein(target, candidate)); + lines.par_sort_by_key(|candidate| levenshtein(&opts.target, candidate)); let mut out = BufWriter::new(stdout()); for candidate in lines {