mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
gpui_shared_string: Implement SharedString via smol_str (#54649)
This reduces the size of Sharedstring from 32 bytes to 24 while also allowing for small-string optimization, meaning strings with length < 23 bytes will not actually allocate. Release Notes: - N/A or Added/Fixed/Improved ...
This commit is contained in:
parent
b9b50e3b9e
commit
58d3a9eef4
9 changed files with 100 additions and 43 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -7839,10 +7839,9 @@ dependencies = [
|
|||
name = "gpui_shared_string"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"gpui_util",
|
||||
"schemars 1.0.4",
|
||||
"serde",
|
||||
"smol_str",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -16527,9 +16526,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "smol_str"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7a918bd2a9951d18ee6e48f076843e8e73a9a5d22cf05bcd4b7a81bdd04e17"
|
||||
checksum = "4aaa7368fcf4852a4c2dd92df0cace6a71f2091ca0a23391ce7f3a31833f1523"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ impl StyledText {
|
|||
|
||||
/// Set the text runs for this piece of text.
|
||||
pub fn with_runs(mut self, runs: Vec<TextRun>) -> Self {
|
||||
let mut text = &**self.text;
|
||||
let mut text = &*self.text;
|
||||
for run in &runs {
|
||||
text = text.get(run.len..).unwrap_or_else(|| {
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
|
|||
|
|
@ -784,7 +784,7 @@ mod tests {
|
|||
}],
|
||||
len: text.len(),
|
||||
}),
|
||||
text: SharedString::new(text.to_string()),
|
||||
text: SharedString::new(text),
|
||||
decoration_runs: SmallVec::from(decorations.to_vec()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2933,9 +2933,6 @@ impl Window {
|
|||
/// Push a text style onto the stack, and call a function with that style active.
|
||||
/// Use [`Window::text_style`] to get the current, combined text style. This method
|
||||
/// should only be called as part of element drawing.
|
||||
// This function is called in a highly recursive manner in editor
|
||||
// prepainting, make sure its inlined to reduce the stack burden
|
||||
#[inline]
|
||||
pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Self) -> R,
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@ edition.workspace = true
|
|||
path = "gpui_shared_string.rs"
|
||||
|
||||
[dependencies]
|
||||
derive_more.workspace = true
|
||||
gpui_util.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
smol_str = "0.3.6"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -1,27 +1,35 @@
|
|||
use derive_more::{Deref, DerefMut};
|
||||
|
||||
use gpui_util::arc_cow::ArcCow;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
borrow::{Borrow, Cow},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smol_str::SmolStr;
|
||||
|
||||
/// A shared string is an immutable string that can be cheaply cloned in GPUI
|
||||
/// tasks. Essentially an abstraction over an `Arc<str>` and `&'static str`,
|
||||
#[derive(Deref, DerefMut, Eq, PartialEq, PartialOrd, Ord, Hash, Clone)]
|
||||
pub struct SharedString(ArcCow<'static, str>);
|
||||
/// currently backed by a [`SmolStr`].
|
||||
#[derive(Eq, PartialEq, PartialOrd, Ord, Hash, Clone)]
|
||||
pub struct SharedString(SmolStr);
|
||||
|
||||
impl std::ops::Deref for SharedString {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl SharedString {
|
||||
/// Creates a static [`SharedString`] from a `&'static str`.
|
||||
pub const fn new_static(str: &'static str) -> Self {
|
||||
Self(ArcCow::Borrowed(str))
|
||||
Self(SmolStr::new_static(str))
|
||||
}
|
||||
|
||||
/// Creates a [`SharedString`] from anything that can become an `Arc<str>`
|
||||
pub fn new(str: impl Into<Arc<str>>) -> Self {
|
||||
SharedString(ArcCow::Owned(str.into()))
|
||||
/// Creates a [`SharedString`].
|
||||
pub fn new(str: impl AsRef<str>) -> Self {
|
||||
SharedString(SmolStr::new(str))
|
||||
}
|
||||
|
||||
/// Get a &str from the underlying string.
|
||||
|
|
@ -46,7 +54,7 @@ impl JsonSchema for SharedString {
|
|||
|
||||
impl Default for SharedString {
|
||||
fn default() -> Self {
|
||||
Self(ArcCow::Borrowed(""))
|
||||
Self::new_static("")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +78,7 @@ impl std::fmt::Debug for SharedString {
|
|||
|
||||
impl std::fmt::Display for SharedString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.as_ref())
|
||||
write!(f, "{}", self.0.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,29 +107,79 @@ impl<'a> PartialEq<&'a str> for SharedString {
|
|||
}
|
||||
|
||||
impl From<&SharedString> for SharedString {
|
||||
fn from(value: &SharedString) -> Self {
|
||||
value.clone()
|
||||
#[inline]
|
||||
fn from(s: &SharedString) -> SharedString {
|
||||
s.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: &str) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&mut str> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: &mut str) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&String> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: &String) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for SharedString {
|
||||
#[inline(always)]
|
||||
fn from(text: String) -> Self {
|
||||
SharedString(SmolStr::from(text))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: Box<str>) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<str>> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: Arc<str>) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Arc<str>> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: &Arc<str>) -> SharedString {
|
||||
SharedString(SmolStr::from(s.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Cow<'a, str>> for SharedString {
|
||||
#[inline]
|
||||
fn from(s: Cow<'a, str>) -> SharedString {
|
||||
SharedString(SmolStr::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SharedString> for Arc<str> {
|
||||
fn from(val: SharedString) -> Self {
|
||||
match val.0 {
|
||||
ArcCow::Borrowed(borrowed) => Arc::from(borrowed),
|
||||
ArcCow::Owned(owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
|
||||
fn from(value: T) -> Self {
|
||||
Self(value.into())
|
||||
#[inline(always)]
|
||||
fn from(text: SharedString) -> Self {
|
||||
text.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SharedString> for String {
|
||||
fn from(val: SharedString) -> Self {
|
||||
val.0.to_string()
|
||||
#[inline(always)]
|
||||
fn from(text: SharedString) -> Self {
|
||||
text.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +198,6 @@ impl<'de> Deserialize<'de> for SharedString {
|
|||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Ok(SharedString::from(s))
|
||||
Ok(SharedString::new(&s))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3627,7 +3627,7 @@ async fn save_keybinding_update(
|
|||
};
|
||||
|
||||
let source = settings::KeybindUpdateTarget {
|
||||
context: action_mapping.context.as_ref().map(|a| &***a),
|
||||
context: action_mapping.context.as_deref(),
|
||||
keystrokes: &action_mapping.keystrokes,
|
||||
action_name: existing.action().name,
|
||||
action_arguments: new_args,
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ impl ParseStepLanguage {
|
|||
fn name(&self) -> SharedString {
|
||||
match self {
|
||||
ParseStepLanguage::Loaded { language } => language.name().0,
|
||||
ParseStepLanguage::Pending { name } => name.into(),
|
||||
ParseStepLanguage::Pending { name } => name.clone().into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ impl PromptStore {
|
|||
let metadata = metadata_cache
|
||||
.metadata
|
||||
.iter()
|
||||
.find(|metadata| metadata.title.as_ref().map(|title| &***title) == Some(title))?;
|
||||
.find(|metadata| metadata.title.as_deref() == Some(title))?;
|
||||
Some(metadata.id)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue