Skip to content

Commit

Permalink
perf: prefer smaller possibly stack allocated strings (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret authored Dec 20, 2024
1 parent d03466c commit ccbe695
Show file tree
Hide file tree
Showing 10 changed files with 648 additions and 124 deletions.
49 changes: 44 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ serde = { version = "1.0.130", features = ["derive", "rc"] }
thiserror = "2"
url = "2.5.3"
deno_error = "0.5.1"
capacity_builder = "0.4.0"
capacity_builder = { version = "0.5.0", features = ["ecow", "hipstr"] }
hipstr = "0.6"
ecow = { version = "0.2.3", features = ["serde"] }

[dev-dependencies]
divan = "0.1.17"
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.80.0"
channel = "1.83.0"
components = ["clippy", "rustfmt"]
profile = "minimal"
31 changes: 18 additions & 13 deletions src/jsr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::borrow::Cow;

use capacity_builder::FastDisplay;
use capacity_builder::CapacityDisplay;
use capacity_builder::StringAppendable;
use capacity_builder::StringType;
use serde::Deserialize;
Expand All @@ -24,7 +24,7 @@ use crate::package::PackageReqReferenceParseError;
///
/// This wraps PackageReqReference in order to prevent accidentally
/// mixing this with other schemes.
#[derive(Clone, Debug, PartialEq, Eq, Hash, FastDisplay)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, CapacityDisplay)]
pub struct JsrPackageReqReference(PackageReqReference);

impl<'a> StringAppendable<'a> for &'a JsrPackageReqReference {
Expand Down Expand Up @@ -77,7 +77,9 @@ impl JsrPackageReqReference {
///
/// This wraps PackageNvReference in order to prevent accidentally
/// mixing this with other schemes.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, FastDisplay)]
#[derive(
Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, CapacityDisplay,
)]
pub struct JsrPackageNvReference(PackageNvReference);

impl JsrPackageNvReference {
Expand Down Expand Up @@ -142,7 +144,7 @@ impl<'de> Deserialize<'de> for JsrPackageNvReference {
where
D: serde::Deserializer<'de>,
{
let text = String::deserialize(deserializer)?;
let text: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
match Self::from_str(&text) {
Ok(req) => Ok(req),
Err(err) => Err(serde::de::Error::custom(err)),
Expand Down Expand Up @@ -178,7 +180,9 @@ pub enum JsrDepPackageReqParseError {
}

/// A package constraint for a JSR dependency which could be from npm or JSR.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, FastDisplay)]
#[derive(
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, CapacityDisplay,
)]
pub struct JsrDepPackageReq {
pub kind: PackageKind,
pub req: PackageReq,
Expand Down Expand Up @@ -208,7 +212,7 @@ impl<'de> Deserialize<'de> for JsrDepPackageReq {
where
D: serde::Deserializer<'de>,
{
let text = String::deserialize(deserializer)?;
let text: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
match Self::from_str_loose(&text) {
Ok(req) => Ok(req),
Err(err) => Err(serde::de::Error::custom(err)),
Expand Down Expand Up @@ -265,13 +269,14 @@ impl JsrDepPackageReq {
/// Outputs a normalized string representation of this dependency.
///
/// Note: The normalized string is not safe for a URL. It's best used for serialization.
pub fn to_string_normalized(&self) -> String {
format!(
"{}{}@{}",
self.kind.scheme_with_colon(),
self.req.name,
self.req.version_req.inner()
)
pub fn to_string_normalized(&self) -> crate::StackString {
capacity_builder::StringBuilder::build(|builder| {
builder.append(self.kind.scheme_with_colon());
builder.append(&self.req.name);
builder.append('@');
builder.append(self.req.version_req.inner());
})
.unwrap()
}
}

Expand Down
29 changes: 20 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
#![deny(clippy::print_stderr)]
#![deny(clippy::print_stdout)]

use std::borrow::Cow;
use std::cmp::Ordering;
use std::fmt;
use std::hash::Hash;

use capacity_builder::FastDisplay;
use capacity_builder::CapacityDisplay;
use capacity_builder::StringAppendable;
use capacity_builder::StringBuilder;
use capacity_builder::StringType;
Expand All @@ -21,6 +22,12 @@ pub mod npm;
pub mod package;
mod range;
mod specifier;
mod string;

/// A smaller two-byte vector.
pub type CowVec<T> = ecow::EcoVec<T>;
pub use string::SmallStackString;
pub use string::StackString;

pub use self::specifier::VersionReqSpecifierParseError;

Expand All @@ -44,13 +51,15 @@ pub struct VersionParseError {
source: monch::ParseErrorFailureError,
}

#[derive(Clone, Debug, PartialEq, Eq, Default, Hash, FastDisplay)]
pub type VersionPreOrBuild = SmallStackString;

#[derive(Clone, Debug, PartialEq, Eq, Default, Hash, CapacityDisplay)]
pub struct Version {
pub major: u64,
pub minor: u64,
pub patch: u64,
pub pre: Vec<String>,
pub build: Vec<String>,
pub pre: CowVec<VersionPreOrBuild>,
pub build: CowVec<VersionPreOrBuild>,
}

impl<'a> StringAppendable<'a> for &'a Version {
Expand Down Expand Up @@ -98,7 +107,7 @@ impl<'de> Deserialize<'de> for Version {
where
D: serde::Deserializer<'de>,
{
let text = String::deserialize(deserializer)?;
let text: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
match Version::parse_standard(&text) {
Ok(version) => Ok(version),
Err(err) => Err(serde::de::Error::custom(err)),
Expand Down Expand Up @@ -197,12 +206,14 @@ pub(crate) fn is_valid_tag(value: &str) -> bool {
npm::is_valid_npm_tag(value)
}

pub type PackageTag = SmallStackString;

#[derive(
Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, FastDisplay,
Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, CapacityDisplay,
)]
pub enum RangeSetOrTag {
RangeSet(VersionRangeSet),
Tag(String),
Tag(PackageTag),
}

impl<'a> StringAppendable<'a> for &'a RangeSetOrTag {
Expand Down Expand Up @@ -233,7 +244,7 @@ impl RangeSetOrTag {
/// A version constraint.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VersionReq {
raw_text: String,
raw_text: SmallStackString,
inner: RangeSetOrTag,
}

Expand All @@ -254,7 +265,7 @@ impl Hash for VersionReq {
impl VersionReq {
/// Creates a version requirement without examining the raw text.
pub fn from_raw_text_and_inner(
raw_text: String,
raw_text: SmallStackString,
inner: RangeSetOrTag,
) -> Self {
Self { raw_text, inner }
Expand Down
Loading

0 comments on commit ccbe695

Please sign in to comment.