Skip to content

Commit e82545d

Browse files
committed
perf: cow map
1 parent 107624e commit e82545d

File tree

9 files changed

+97
-76
lines changed

9 files changed

+97
-76
lines changed

benches/bench.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ fn bench_rspack_sources(criterion: &mut Criterion) {
253253
benchmark_parse_source_map_from_json,
254254
);
255255

256-
group.bench_function("source_map_as_borrowed", benchmark_source_map_as_borrowed);
256+
group
257+
.bench_function("source_map_as_borrowed", benchmark_source_map_as_borrowed);
257258

258259
group.bench_function(
259260
"stringify_source_map_to_json",

src/cached_source.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use std::{
22
borrow::Cow,
3-
hash::{BuildHasherDefault, Hash, Hasher},
4-
sync::{Arc, OnceLock},
3+
hash::{Hash, Hasher},
4+
sync::OnceLock,
55
};
66

7-
use dashmap::{mapref::entry::Entry, DashMap};
87
use rustc_hash::FxHasher;
98

109
use crate::{
@@ -116,22 +115,32 @@ impl Source for CachedSource {
116115
self.0.borrow_owner().inner.size()
117116
}
118117

119-
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
118+
fn map<'a>(&'a self, options: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
120119
if options.columns {
121120
self.0.with_dependent(|owner, dependent| {
122121
dependent
123122
.cached_colomns_map
124-
.get_or_init(|| owner.inner.map(options).map(|m| m.into_owned()))
123+
.get_or_init(|| {
124+
owner
125+
.inner
126+
.map(options)
127+
.map(|m| m.as_ref().clone().into_owned())
128+
})
125129
.as_ref()
126-
.map(|m| m.as_borrowed())
130+
.map(Cow::Borrowed)
127131
})
128132
} else {
129133
self.0.with_dependent(|owner, dependent| {
130134
dependent
131135
.cached_line_only_map
132-
.get_or_init(|| owner.inner.map(options).map(|m| m.into_owned()))
136+
.get_or_init(|| {
137+
owner
138+
.inner
139+
.map(options)
140+
.map(|m| m.as_ref().clone().into_owned())
141+
})
133142
.as_ref()
134-
.map(|m| m.as_borrowed())
143+
.map(Cow::Borrowed)
135144
})
136145
}
137146
}

src/concat_source.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ use crate::{
3939
/// "Hello World\nconsole.log('test');\nconsole.log('test2');\nHello2\n"
4040
/// );
4141
/// assert_eq!(
42-
/// source.map(&MapOptions::new(false)).unwrap(),
43-
/// SourceMap::from_json(
42+
/// source.map(&MapOptions::new(false)).unwrap().as_ref(),
43+
/// &SourceMap::from_json(
4444
/// r#"{
4545
/// "version": 3,
4646
/// "mappings": ";AAAA;AACA;ACDA",
@@ -156,8 +156,8 @@ impl Source for ConcatSource {
156156
self.children().iter().map(|child| child.size()).sum()
157157
}
158158

159-
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
160-
get_map(self, options)
159+
fn map<'a>(&'a self, options: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
160+
get_map(self, options).map(Cow::Owned)
161161
}
162162

163163
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
@@ -376,8 +376,8 @@ mod tests {
376376
assert_eq!(source.size(), 62);
377377
assert_eq!(source.source(), expected_source);
378378
assert_eq!(
379-
source.map(&MapOptions::new(false)).unwrap(),
380-
SourceMap::from_json(
379+
source.map(&MapOptions::new(false)).unwrap().as_ref(),
380+
&SourceMap::from_json(
381381
r#"{
382382
"version": 3,
383383
"mappings": ";AAAA;AACA;ACDA",
@@ -392,8 +392,8 @@ mod tests {
392392
.unwrap()
393393
);
394394
assert_eq!(
395-
source.map(&MapOptions::default()).unwrap(),
396-
SourceMap::from_json(
395+
source.map(&MapOptions::default()).unwrap().as_ref(),
396+
&SourceMap::from_json(
397397
r#"{
398398
"version": 3,
399399
"mappings": ";AAAA;AACA;ACDA",
@@ -426,8 +426,8 @@ mod tests {
426426
assert_eq!(source.size(), 62);
427427
assert_eq!(source.source(), expected_source);
428428
assert_eq!(
429-
source.map(&MapOptions::new(false)).unwrap(),
430-
SourceMap::from_json(
429+
source.map(&MapOptions::new(false)).unwrap().as_ref(),
430+
&SourceMap::from_json(
431431
r#"{
432432
"version": 3,
433433
"mappings": ";AAAA;AACA;ACDA",
@@ -442,8 +442,8 @@ mod tests {
442442
.unwrap()
443443
);
444444
assert_eq!(
445-
source.map(&MapOptions::default()).unwrap(),
446-
SourceMap::from_json(
445+
source.map(&MapOptions::default()).unwrap().as_ref(),
446+
&SourceMap::from_json(
447447
r#"{
448448
"version": 3,
449449
"mappings": ";AAAA;AACA;ACDA",
@@ -476,8 +476,8 @@ mod tests {
476476
assert_eq!(source.size(), 62);
477477
assert_eq!(source.source(), expected_source);
478478
assert_eq!(
479-
source.map(&MapOptions::new(false)).unwrap(),
480-
SourceMap::from_json(
479+
source.map(&MapOptions::new(false)).unwrap().as_ref(),
480+
&SourceMap::from_json(
481481
r#"{
482482
"version": 3,
483483
"mappings": ";AAAA;AACA;ACDA",
@@ -492,8 +492,8 @@ mod tests {
492492
.unwrap()
493493
);
494494
assert_eq!(
495-
source.map(&MapOptions::default()).unwrap(),
496-
SourceMap::from_json(
495+
source.map(&MapOptions::default()).unwrap().as_ref(),
496+
&SourceMap::from_json(
497497
r#"{
498498
"version": 3,
499499
"mappings": ";AAAA;AACA;ACDA",
@@ -542,7 +542,7 @@ mod tests {
542542
assert_eq!(source.buffer(), expected_source.as_bytes());
543543

544544
let map = source.map(&MapOptions::new(false)).unwrap();
545-
assert_eq!(map, expected_map1);
545+
assert_eq!(map.as_ref(), &expected_map1);
546546

547547
// TODO: test hash
548548
}
@@ -578,8 +578,8 @@ mod tests {
578578
]);
579579

580580
assert_eq!(
581-
source.map(&MapOptions::default()).unwrap(),
582-
SourceMap::from_json(
581+
source.map(&MapOptions::default()).unwrap().as_ref(),
582+
&SourceMap::from_json(
583583
r#"{
584584
"mappings": "AAAA,K,CCAA,M;ADAA;;ACAA",
585585
"names": [],

src/original_source.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ impl Source for OriginalSource {
6767
self.value.len()
6868
}
6969

70-
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
71-
get_map(self, options)
70+
fn map<'a>(&'a self, options: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
71+
get_map(self, options).map(Cow::Owned)
7272
}
7373

7474
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {

src/raw_source.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl Source for RawSource {
148148
}
149149
}
150150

151-
fn map(&self, _: &MapOptions) -> Option<SourceMap> {
151+
fn map<'a>(&'a self, _: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
152152
None
153153
}
154154

@@ -300,7 +300,7 @@ impl Source for RawStringSource {
300300
self.0.len()
301301
}
302302

303-
fn map(&self, _: &MapOptions) -> Option<SourceMap> {
303+
fn map<'a>(&'a self, _: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
304304
None
305305
}
306306

@@ -433,7 +433,7 @@ impl Source for RawBufferSource {
433433
self.value.len()
434434
}
435435

436-
fn map(&self, _: &MapOptions) -> Option<SourceMap> {
436+
fn map<'a>(&'a self, _: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
437437
None
438438
}
439439

src/replace_source.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,15 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for ReplaceSource<T> {
265265
self.source().len()
266266
}
267267

268-
fn map(&self, options: &crate::MapOptions) -> Option<SourceMap> {
268+
fn map<'a>(
269+
&'a self,
270+
options: &crate::MapOptions,
271+
) -> Option<Cow<'a, SourceMap<'a>>> {
269272
let replacements = &self.replacements;
270273
if replacements.is_empty() {
271274
return self.inner.map(options);
272275
}
273-
get_map(self, options)
276+
get_map(self, options).map(Cow::Owned)
274277
}
275278

276279
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {

src/source.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub trait Source:
3939
fn size(&self) -> usize;
4040

4141
/// Get the [SourceMap].
42-
fn map(&self, options: &MapOptions) -> Option<SourceMap<'_>>;
42+
fn map(&self, options: &MapOptions) -> Option<Cow<SourceMap<'_>>>;
4343

4444
/// Update hash based on the source.
4545
fn update_hash(&self, state: &mut dyn Hasher) {
@@ -67,7 +67,7 @@ impl Source for BoxSource {
6767
self.as_ref().size()
6868
}
6969

70-
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
70+
fn map<'a>(&'a self, options: &MapOptions) -> Option<Cow<'a, SourceMap<'a>>> {
7171
self.as_ref().map(options)
7272
}
7373

0 commit comments

Comments
 (0)