Skip to content

Commit 792ad27

Browse files
authored
perf: Use ustr for RuntimeSpec (#10480)
1 parent 60e8b26 commit 792ad27

File tree

21 files changed

+159
-172
lines changed

21 files changed

+159
-172
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/node_binding/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ serde = { workspace = true }
106106
serde_json = { workspace = true }
107107
swc_core = { workspace = true, default-features = false, features = ["ecma_transforms_react"] }
108108
tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "tracing"] }
109+
ustr = { workspace = true }
109110

110111
[target.'cfg(not(target_family = "wasm"))'.dependencies]
111112
tokio = { workspace = true, features = ["parking_lot"] }

crates/node_binding/src/chunk_graph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{ptr::NonNull, sync::Arc};
1+
use std::ptr::NonNull;
22

33
use napi::{Either, Result};
44
use napi_derive::napi;
@@ -173,8 +173,8 @@ impl JsChunkGraph {
173173
) -> napi::Result<Option<&str>> {
174174
let compilation = self.as_ref()?;
175175
let Some(runtime) = js_runtime.map(|js_runtime| match js_runtime {
176-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
177-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
176+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
177+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
178178
}) else {
179179
return Ok(None);
180180
};

crates/node_binding/src/compilation/code_generation_results.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::sync::Arc;
2-
31
use napi::Either;
42
use rspack_core::{Reflector, WeakBindingCell};
53
use rustc_hash::FxHashMap;
@@ -112,8 +110,8 @@ impl CodeGenerationResults {
112110
pub fn get(&self, module: ModuleObjectRef, runtime: JsRuntimeSpec) -> napi::Result<Reflector> {
113111
self.with_ref(|code_generation_results| {
114112
let rt: Option<rspack_core::RuntimeSpec> = runtime.map(|val| match val {
115-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
116-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
113+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
114+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
117115
});
118116

119117
let code_generation_result = code_generation_results.get(&module.identifier, rt.as_ref());

crates/node_binding/src/exports_info.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{ptr::NonNull, sync::Arc};
1+
use std::ptr::NonNull;
22

33
use napi::Either;
44
use napi_derive::napi;
@@ -40,8 +40,8 @@ impl JsExportsInfo {
4040
pub fn is_used(&self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
4141
let module_graph = self.as_ref()?;
4242
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
43-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
44-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
43+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
44+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
4545
});
4646
Ok(self.exports_info.is_used(&module_graph, runtime.as_ref()))
4747
}
@@ -50,8 +50,8 @@ impl JsExportsInfo {
5050
pub fn is_module_used(&self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
5151
let module_graph = self.as_ref()?;
5252
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
53-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
54-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
53+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
54+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
5555
});
5656
Ok(
5757
self
@@ -64,8 +64,8 @@ impl JsExportsInfo {
6464
pub fn set_used_in_unknown_way(&mut self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
6565
let mut module_graph = self.as_mut()?;
6666
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
67-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
68-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
67+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
68+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
6969
});
7070
Ok(
7171
self
@@ -85,8 +85,8 @@ impl JsExportsInfo {
8585
) -> napi::Result<u32> {
8686
let module_graph = self.as_ref()?;
8787
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
88-
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
89-
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
88+
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
89+
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
9090
});
9191
let used = match js_name {
9292
Either::A(s) => self

crates/node_binding/src/module_graph.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use std::{ptr::NonNull, sync::Arc};
1+
use std::ptr::NonNull;
22

33
use napi::{Either, Env, JsString};
44
use napi_derive::napi;
55
use rspack_core::{Compilation, ModuleGraph, RuntimeSpec};
6-
use rustc_hash::FxHashSet;
76

87
use crate::{
98
DependencyObject, JsExportsInfo, ModuleGraphConnectionWrapper, ModuleObject, ModuleObjectRef,
@@ -81,13 +80,13 @@ impl JsModuleGraph {
8180
) -> napi::Result<Option<Either<bool, Vec<JsString<'a>>>>> {
8281
let (_, module_graph) = self.as_ref()?;
8382

84-
let mut runtime: FxHashSet<Arc<str>> = FxHashSet::default();
83+
let mut runtime = ustr::UstrSet::default();
8584
match js_runtime {
8685
Either::A(s) => {
87-
runtime.insert(Arc::from(s));
86+
runtime.insert(s.into());
8887
}
8988
Either::B(vec) => {
90-
runtime.extend(vec.into_iter().map(Arc::from));
89+
runtime.extend(vec.iter().map(String::as_str).map(ustr::Ustr::from));
9190
}
9291
};
9392
let used_exports =

crates/rspack_cacheable/src/with/as_ref_str.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,16 @@ impl AsRefStrConverter for Box<str> {
100100
s.into()
101101
}
102102
}
103+
104+
// for Ustr
105+
impl AsRefStrConverter for ustr::Ustr {
106+
fn as_str(&self) -> &str {
107+
self
108+
}
109+
fn from_str(s: &str) -> Self
110+
where
111+
Self: Sized,
112+
{
113+
s.into()
114+
}
115+
}

crates/rspack_collections/src/identifier.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
use dashmap::{DashMap, DashSet};
1010
use hashlink::{LinkedHashMap, LinkedHashSet};
1111
use indexmap::{IndexMap, IndexSet};
12-
use rspack_cacheable::{cacheable, with::AsPreset};
12+
use rspack_cacheable::{cacheable, with, with::AsPreset};
1313
use serde::Serialize;
1414
use ustr::Ustr;
1515

@@ -92,3 +92,16 @@ impl fmt::Display for Identifier {
9292
write!(f, "{}", self.to_string())
9393
}
9494
}
95+
96+
// for Identifier
97+
impl with::AsRefStrConverter for Identifier {
98+
fn as_str(&self) -> &str {
99+
self.0.as_str()
100+
}
101+
fn from_str(s: &str) -> Self
102+
where
103+
Self: Sized,
104+
{
105+
s.into()
106+
}
107+
}

crates/rspack_core/src/build_chunk_graph/code_splitter.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{
22
collections::HashSet as RawHashSet,
33
hash::{BuildHasherDefault, Hash},
4-
sync::{atomic::AtomicU32, Arc},
4+
sync::atomic::AtomicU32,
55
};
66

77
use indexmap::{IndexMap as RawIndexMap, IndexSet as RawIndexSet};
@@ -130,12 +130,12 @@ impl ChunkGroupInfo {
130130
}
131131

132132
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
133-
pub(crate) struct OptionalRuntimeSpec(pub Vec<Arc<str>>);
133+
pub(crate) struct OptionalRuntimeSpec(pub Vec<ustr::Ustr>);
134134

135135
impl From<Option<RuntimeSpec>> for OptionalRuntimeSpec {
136136
fn from(value: Option<RuntimeSpec>) -> Self {
137137
let mut vec = value.unwrap_or_default().into_iter().collect::<Vec<_>>();
138-
vec.sort();
138+
vec.sort_unstable();
139139
Self(vec)
140140
}
141141
}
@@ -1694,8 +1694,8 @@ Or do you want to use the entrypoints '{name}' and '{runtime}' independently on
16941694
.chunk_groups_for_merging
16951695
.insert((target_ukey, process_block));
16961696
let mut updated = false;
1697-
for r in runtime.iter() {
1698-
updated |= target_cgi.runtime.insert(r.clone());
1697+
for &r in runtime.iter() {
1698+
updated |= target_cgi.runtime.insert(r);
16991699
}
17001700
if updated {
17011701
self.outdated_chunk_group_info.insert(target_ukey);

crates/rspack_core/src/build_chunk_graph/new_code_splitter.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
use std::{
2-
borrow::Cow,
3-
hash::BuildHasherDefault,
4-
iter::once,
5-
sync::{atomic::AtomicU32, Arc},
6-
};
1+
use std::{borrow::Cow, hash::BuildHasherDefault, iter::once, sync::atomic::AtomicU32};
72

83
use dashmap::mapref::one::Ref;
94
use indexmap::IndexSet;
@@ -421,7 +416,7 @@ impl CodeSplitter {
421416
Self::get_entry_runtime(entry, compilation, &mut entry_runtime, &mut visited)
422417
{
423418
diagnostics.push(Diagnostic::from(error));
424-
let tmp_runtime = once(Arc::from(entry.clone())).collect::<RuntimeSpec>();
419+
let tmp_runtime = once(ustr::Ustr::from(entry.as_str())).collect::<RuntimeSpec>();
425420
entry_runtime.insert(entry, tmp_runtime.clone());
426421
};
427422
}
@@ -695,12 +690,12 @@ impl CodeSplitter {
695690
entry
696691
));
697692
}
698-
let mut runtime = None;
693+
let mut runtime: Option<RuntimeSpec> = None;
699694
for dep in depend_on {
700695
let other_runtime = Self::get_entry_runtime(dep, compilation, entry_runtime, visited)?;
701696
match &mut runtime {
702697
Some(runtime) => {
703-
*runtime = merge_runtime(runtime, &other_runtime);
698+
runtime.extend(&other_runtime);
704699
}
705700
None => {
706701
runtime = Some(other_runtime);

crates/rspack_core/src/chunk.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rspack_hash::{RspackHash, RspackHashDigest};
1212
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet, FxHasher};
1313

1414
use crate::{
15-
chunk_graph_chunk::ChunkId, compare_chunk_group, merge_runtime, sort_group_by_index, ChunkGraph,
15+
chunk_graph_chunk::ChunkId, compare_chunk_group, sort_group_by_index, ChunkGraph,
1616
ChunkGroupByUkey, ChunkGroupOrderKey, ChunkGroupUkey, ChunkHashesArtifact, ChunkIdsArtifact,
1717
ChunkUkey, Compilation, EntryOptions, Filename, ModuleGraph, RenderManifestEntry, RuntimeSpec,
1818
SourceType,
@@ -324,7 +324,7 @@ impl Chunk {
324324
new_chunk.add_group(group.ukey);
325325
});
326326
new_chunk.id_name_hints.extend(self.id_name_hints.clone());
327-
new_chunk.runtime = merge_runtime(&new_chunk.runtime, &self.runtime);
327+
new_chunk.runtime.extend(&self.runtime);
328328
}
329329

330330
pub fn can_be_initial(&self, chunk_group_by_ukey: &ChunkGroupByUkey) -> bool {

crates/rspack_core/src/concatenated_module.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ impl Module for ConcatenatedModule {
630630
Some(Cow::Owned(
631631
generation_runtime
632632
.intersection(self_runtime)
633-
.cloned()
633+
.copied()
634634
.collect::<RuntimeSpec>(),
635635
))
636636
} else {
@@ -1301,7 +1301,7 @@ impl Module for ConcatenatedModule {
13011301
Some(Cow::Owned(
13021302
generation_runtime
13031303
.intersection(self_runtime)
1304-
.cloned()
1304+
.copied()
13051305
.collect::<RuntimeSpec>(),
13061306
))
13071307
} else {

crates/rspack_core/src/exports_info.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ impl ExportInfo {
10371037
let mut max = UsageState::Unused;
10381038
if let Some(runtime) = runtime {
10391039
for item in runtime.iter() {
1040-
let Some(usage) = used_in_runtime.get(item.as_ref()) else {
1040+
let Some(usage) = used_in_runtime.get(item) else {
10411041
continue;
10421042
};
10431043
match usage {
@@ -1081,7 +1081,7 @@ impl ExportInfo {
10811081
if let Some(runtime) = runtime {
10821082
if runtime
10831083
.iter()
1084-
.all(|item| !used_in_runtime.contains_key(item.as_ref()))
1084+
.all(|item| !used_in_runtime.contains_key(item))
10851085
{
10861086
return None;
10871087
}
@@ -1295,12 +1295,10 @@ impl ExportInfo {
12951295
) -> bool {
12961296
if let Some(runtime) = runtime {
12971297
let export_info_mut = mg.get_export_info_mut_by_id(self);
1298-
let used_in_runtime = export_info_mut
1299-
.used_in_runtime
1300-
.get_or_insert(HashMap::default());
1298+
let used_in_runtime = export_info_mut.used_in_runtime.get_or_insert_default();
13011299
let mut changed = false;
1302-
for k in runtime.iter() {
1303-
match used_in_runtime.entry(k.clone()) {
1300+
for &k in runtime.iter() {
1301+
match used_in_runtime.entry(k) {
13041302
Entry::Occupied(mut occ) => match (&new_value, occ.get()) {
13051303
(new, _) if new == &UsageState::Unused => {
13061304
occ.remove();
@@ -1344,13 +1342,11 @@ impl ExportInfo {
13441342
) -> bool {
13451343
if let Some(runtime) = runtime {
13461344
let export_info_mut = mg.get_export_info_mut_by_id(self);
1347-
let used_in_runtime = export_info_mut
1348-
.used_in_runtime
1349-
.get_or_insert(HashMap::default());
1345+
let used_in_runtime = export_info_mut.used_in_runtime.get_or_insert_default();
13501346
let mut changed = false;
13511347

1352-
for k in runtime.iter() {
1353-
match used_in_runtime.entry(k.clone()) {
1348+
for &k in runtime.iter() {
1349+
match used_in_runtime.entry(k) {
13541350
Entry::Occupied(mut occ) => match (&new_value, occ.get()) {
13551351
(new, old) if condition(old) && new == &UsageState::Unused => {
13561352
occ.remove();
@@ -1507,7 +1503,7 @@ pub struct ExportInfoData {
15071503
has_use_in_runtime_info: bool,
15081504
can_mangle_use: Option<bool>,
15091505
global_used: Option<UsageState>,
1510-
used_in_runtime: Option<HashMap<Arc<str>, UsageState>>,
1506+
used_in_runtime: Option<ustr::UstrMap<UsageState>>,
15111507
}
15121508

15131509
#[derive(Debug, Hash, Clone, Copy)]

0 commit comments

Comments
 (0)