mirror of
https://github.com/clap-rs/clap
synced 2024-12-05 02:29:12 +00:00
perf: Let users choose Str implementation
The binary size and performance difference is enough to make it configurable. Code size: - default: 565.7 KiB - perf: 578.5 KiB Build time: - default: 9.1706 us - perf: 7.0479 us Parse time: - default: 12.673 us - perf: 8.1708 us Parse with subcommand time: - default: 12.112 us - perf: 7.9874 us
This commit is contained in:
parent
71752f56ea
commit
fc499ac0ec
6 changed files with 146 additions and 37 deletions
|
@ -60,7 +60,7 @@ default = [
|
|||
"suggestions",
|
||||
]
|
||||
debug = ["clap_derive/debug", "dep:backtrace"] # Enables debug messages
|
||||
unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "unstable-replace", "unstable-grouped"] # for docs.rs
|
||||
unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "perf", "unstable-replace", "unstable-grouped"] # for docs.rs
|
||||
|
||||
# Used in default
|
||||
std = [] # support for no_std in a backwards-compatible way
|
||||
|
@ -74,6 +74,7 @@ cargo = ["dep:once_cell"] # Disable if you're not using Cargo, enables Cargo-env
|
|||
wrap_help = ["dep:terminal_size", "textwrap/terminal_size"]
|
||||
env = [] # Use environment variables during arg parsing
|
||||
unicode = ["textwrap/unicode-width", "dep:unicase"] # Support for unicode characters in arguments and help messages
|
||||
perf = [] # Optimize for runtime performance
|
||||
|
||||
# In-work features
|
||||
unstable-replace = []
|
||||
|
|
4
Makefile
4
Makefile
|
@ -15,8 +15,8 @@ MSRV?=1.60.0
|
|||
_FEATURES = minimal default wasm full debug release
|
||||
_FEATURES_minimal = --no-default-features --features "std"
|
||||
_FEATURES_default =
|
||||
_FEATURES_wasm = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped"
|
||||
_FEATURES_full = --features "deprecated derive cargo env unicode unstable-replace unstable-grouped wrap_help"
|
||||
_FEATURES_wasm = --features "deprecated derive cargo env unicode perf unstable-replace unstable-grouped"
|
||||
_FEATURES_full = --features "deprecated derive cargo env unicode perf unstable-replace unstable-grouped wrap_help"
|
||||
_FEATURES_next = ${_FEATURES_full} --features unstable-v5
|
||||
_FEATURES_debug = ${_FEATURES_full} --features debug
|
||||
_FEATURES_release = ${_FEATURES_full} --release
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//! * **env**: Turns on the usage of environment variables during parsing.
|
||||
//! * **unicode**: Turns on support for unicode characters (including emoji) in arguments and help messages.
|
||||
//! * **wrap_help**: Turns on the help text wrapping feature, based on the terminal size.
|
||||
//! * **perf**: Optimized for runtime performance.
|
||||
//!
|
||||
//! #### Experimental features
|
||||
//!
|
||||
|
|
|
@ -16,6 +16,8 @@ pub(crate) use self::flat_map::Entry;
|
|||
pub(crate) use self::flat_map::FlatMap;
|
||||
pub(crate) use self::flat_set::FlatSet;
|
||||
pub(crate) use self::graph::ChildGraph;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use self::str::Inner as StrInner;
|
||||
pub(crate) use self::str_to_bool::str_to_bool;
|
||||
pub(crate) use self::str_to_bool::FALSE_LITERALS;
|
||||
pub(crate) use self::str_to_bool::TRUE_LITERALS;
|
||||
|
|
|
@ -40,12 +40,34 @@ impl From<&'_ OsStr> for OsStr {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "perf")]
|
||||
impl From<crate::Str> for OsStr {
|
||||
fn from(id: crate::Str) -> Self {
|
||||
match id.into_inner() {
|
||||
crate::util::StrInner::Static(s) => Self::from_static_ref(std::ffi::OsStr::new(s)),
|
||||
crate::util::StrInner::Owned(s) => Self::from_ref(std::ffi::OsStr::new(s.as_ref())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "perf"))]
|
||||
impl From<crate::Str> for OsStr {
|
||||
fn from(id: crate::Str) -> Self {
|
||||
Self::from_ref(std::ffi::OsStr::new(id.as_str()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "perf")]
|
||||
impl From<&'_ crate::Str> for OsStr {
|
||||
fn from(id: &'_ crate::Str) -> Self {
|
||||
match id.clone().into_inner() {
|
||||
crate::util::StrInner::Static(s) => Self::from_static_ref(std::ffi::OsStr::new(s)),
|
||||
crate::util::StrInner::Owned(s) => Self::from_ref(std::ffi::OsStr::new(s.as_ref())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "perf"))]
|
||||
impl From<&'_ crate::Str> for OsStr {
|
||||
fn from(id: &'_ crate::Str) -> Self {
|
||||
Self::from_ref(std::ffi::OsStr::new(id.as_str()))
|
||||
|
@ -214,31 +236,70 @@ impl PartialEq<OsStr> for std::ffi::OsString {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Inner(Box<std::ffi::OsStr>);
|
||||
|
||||
impl Inner {
|
||||
fn from_string(name: std::ffi::OsString) -> Self {
|
||||
Self(name.into_boxed_os_str())
|
||||
#[cfg(feature = "perf")]
|
||||
pub(crate) mod inner {
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum Inner {
|
||||
Static(&'static std::ffi::OsStr),
|
||||
Owned(Box<std::ffi::OsStr>),
|
||||
}
|
||||
|
||||
fn from_ref(name: &std::ffi::OsStr) -> Self {
|
||||
Self(Box::from(name))
|
||||
}
|
||||
impl Inner {
|
||||
pub(crate) fn from_string(name: std::ffi::OsString) -> Self {
|
||||
Self::Owned(name.into_boxed_os_str())
|
||||
}
|
||||
|
||||
fn from_static_ref(name: &'static std::ffi::OsStr) -> Self {
|
||||
Self::from_ref(name)
|
||||
}
|
||||
pub(crate) fn from_ref(name: &std::ffi::OsStr) -> Self {
|
||||
Self::Owned(Box::from(name))
|
||||
}
|
||||
|
||||
fn as_os_str(&self) -> &std::ffi::OsStr {
|
||||
&self.0
|
||||
}
|
||||
pub(crate) fn from_static_ref(name: &'static std::ffi::OsStr) -> Self {
|
||||
Self::Static(name)
|
||||
}
|
||||
|
||||
fn into_os_string(self) -> std::ffi::OsString {
|
||||
self.as_os_str().to_owned()
|
||||
pub(crate) fn as_os_str(&self) -> &std::ffi::OsStr {
|
||||
match self {
|
||||
Self::Static(s) => s,
|
||||
Self::Owned(s) => s.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_os_string(self) -> std::ffi::OsString {
|
||||
self.as_os_str().to_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "perf"))]
|
||||
pub(crate) mod inner {
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Inner(Box<std::ffi::OsStr>);
|
||||
|
||||
impl Inner {
|
||||
pub(crate) fn from_string(name: std::ffi::OsString) -> Self {
|
||||
Self(name.into_boxed_os_str())
|
||||
}
|
||||
|
||||
pub(crate) fn from_ref(name: &std::ffi::OsStr) -> Self {
|
||||
Self(Box::from(name))
|
||||
}
|
||||
|
||||
pub(crate) fn from_static_ref(name: &'static std::ffi::OsStr) -> Self {
|
||||
Self::from_ref(name)
|
||||
}
|
||||
|
||||
pub(crate) fn as_os_str(&self) -> &std::ffi::OsStr {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub(crate) fn into_os_string(self) -> std::ffi::OsString {
|
||||
self.as_os_str().to_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use inner::Inner;
|
||||
|
||||
impl Default for Inner {
|
||||
fn default() -> Self {
|
||||
Self::from_static_ref(std::ffi::OsStr::new(""))
|
||||
|
|
|
@ -23,6 +23,11 @@ impl Str {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "perf")]
|
||||
pub(crate) fn into_inner(self) -> Inner {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Get the raw string of the `Str`
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.name.as_str()
|
||||
|
@ -206,31 +211,70 @@ impl PartialEq<Str> for std::string::String {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Inner(Box<str>);
|
||||
|
||||
impl Inner {
|
||||
fn from_string(name: std::string::String) -> Self {
|
||||
Self(name.into_boxed_str())
|
||||
#[cfg(feature = "perf")]
|
||||
pub(crate) mod inner {
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum Inner {
|
||||
Static(&'static str),
|
||||
Owned(Box<str>),
|
||||
}
|
||||
|
||||
fn from_ref(name: &str) -> Self {
|
||||
Self(Box::from(name))
|
||||
}
|
||||
impl Inner {
|
||||
pub(crate) fn from_string(name: std::string::String) -> Self {
|
||||
Self::Owned(name.into_boxed_str())
|
||||
}
|
||||
|
||||
fn from_static_ref(name: &'static str) -> Self {
|
||||
Self::from_ref(name)
|
||||
}
|
||||
pub(crate) fn from_ref(name: &str) -> Self {
|
||||
Self::Owned(Box::from(name))
|
||||
}
|
||||
|
||||
fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
pub(crate) fn from_static_ref(name: &'static str) -> Self {
|
||||
Self::Static(name)
|
||||
}
|
||||
|
||||
fn into_string(self) -> String {
|
||||
self.as_str().to_owned()
|
||||
pub(crate) fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Static(s) => s,
|
||||
Self::Owned(s) => s.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
self.as_str().to_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "perf"))]
|
||||
pub(crate) mod inner {
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Inner(Box<str>);
|
||||
|
||||
impl Inner {
|
||||
pub(crate) fn from_string(name: std::string::String) -> Self {
|
||||
Self(name.into_boxed_str())
|
||||
}
|
||||
|
||||
pub(crate) fn from_ref(name: &str) -> Self {
|
||||
Self(Box::from(name))
|
||||
}
|
||||
|
||||
pub(crate) fn from_static_ref(name: &'static str) -> Self {
|
||||
Self::from_ref(name)
|
||||
}
|
||||
|
||||
pub(crate) fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
self.as_str().to_owned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use inner::Inner;
|
||||
|
||||
impl Default for Inner {
|
||||
fn default() -> Self {
|
||||
Self::from_static_ref("")
|
||||
|
|
Loading…
Reference in a new issue