Skip to content

Commit 58994d9

Browse files
authored
perf: replace source (#130)
1 parent 6805c7b commit 58994d9

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

src/concat_source.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,27 @@ impl ConcatSource {
100100

101101
impl Source for ConcatSource {
102102
fn source(&self) -> Cow<str> {
103-
let all = self.children().iter().map(|child| child.source()).collect();
104-
Cow::Owned(all)
103+
let children = self.children();
104+
if children.len() == 1 {
105+
children[0].source()
106+
} else {
107+
let all = self.children().iter().map(|child| child.source()).collect();
108+
Cow::Owned(all)
109+
}
105110
}
106111

107112
fn buffer(&self) -> Cow<[u8]> {
108-
let all = self
109-
.children()
110-
.iter()
111-
.map(|child| child.buffer())
112-
.collect::<Vec<_>>()
113-
.concat();
114-
Cow::Owned(all)
113+
let children = self.children();
114+
if children.len() == 1 {
115+
children[0].buffer()
116+
} else {
117+
let all = children
118+
.iter()
119+
.map(|child| child.buffer())
120+
.collect::<Vec<_>>()
121+
.concat();
122+
Cow::Owned(all)
123+
}
115124
}
116125

117126
fn size(&self) -> usize {

src/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ fn stream_chunks_of_source_map_full<'a>(
456456
[(current_generated_line - 1) as usize]
457457
.substring(current_generated_column as usize, usize::MAX);
458458
on_chunk(
459-
Some(Cow::Owned(chunk.to_string())),
459+
Some(Cow::Borrowed(chunk)),
460460
Mapping {
461461
generated_line: current_generated_line,
462462
generated_column: current_generated_column,
@@ -472,7 +472,7 @@ fn stream_chunks_of_source_map_full<'a>(
472472
let chunk =
473473
line_with_indices_list[(current_generated_line as usize) - 1].line;
474474
on_chunk(
475-
Some(Cow::Owned(chunk.to_string())),
475+
Some(Cow::Borrowed(chunk)),
476476
Mapping {
477477
generated_line: current_generated_line,
478478
generated_column: 0,

src/replace_source.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for ReplaceSource<T> {
206206
}
207207

208208
fn buffer(&self) -> Cow<[u8]> {
209-
let source = self.source().to_string();
210-
Cow::Owned(source.into_bytes())
209+
match self.source() {
210+
Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()),
211+
Cow::Owned(s) => Cow::Owned(s.into_bytes()),
212+
}
211213
}
212214

213215
fn size(&self) -> usize {
@@ -407,10 +409,17 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
407409
if next_replacement_pos > pos {
408410
// Emit chunk until replacement
409411
let offset = next_replacement_pos - pos;
410-
let chunk_slice =
411-
&chunk[chunk_pos as usize..(chunk_pos + offset) as usize];
412+
let chunk_slice = match &chunk {
413+
Cow::Borrowed(c) => Cow::Borrowed(
414+
&c[chunk_pos as usize..(chunk_pos + offset) as usize],
415+
),
416+
Cow::Owned(c) => Cow::Owned(
417+
c[chunk_pos as usize..(chunk_pos + offset) as usize]
418+
.to_string(),
419+
),
420+
};
412421
on_chunk(
413-
Some(Cow::Owned(chunk_slice.to_string())),
422+
Some(chunk_slice.clone()),
414423
Mapping {
415424
generated_line: line as u32,
416425
generated_column: ((mapping.generated_column as i64)
@@ -440,16 +449,20 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
440449
original.source_index,
441450
original.original_line,
442451
original.original_column,
443-
chunk_slice,
452+
&chunk_slice,
444453
)
445454
})
446455
{
447456
original.original_column += chunk_slice.len() as u32;
448457
}
449458
}
450459
// Insert replacement content split into chunks by lines
460+
#[allow(unsafe_code)]
461+
// SAFETY: The safety of this operation relies on the fact that the `ReplaceSource` type will not delete the `replacements` during its entire lifetime.
462+
let repl = unsafe {
463+
std::mem::transmute::<&Replacement, &'a Replacement>(&repls[i])
464+
};
451465

452-
let repl = &repls[i];
453466
let lines: Vec<&str> = split_into_lines(&repl.content).collect();
454467
let mut replacement_name_index = mapping
455468
.original
@@ -463,14 +476,14 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
463476
if global_index.is_none() {
464477
let len = name_mapping.len() as u32;
465478
name_mapping.insert(Cow::Borrowed(name), len);
466-
on_name.borrow_mut()(len, Cow::Owned(name.to_string()));
479+
on_name.borrow_mut()(len, Cow::Borrowed(name));
467480
global_index = Some(len);
468481
}
469482
replacement_name_index = global_index;
470483
}
471484
for (m, content_line) in lines.iter().enumerate() {
472485
on_chunk(
473-
Some(Cow::Owned(content_line.to_string())),
486+
Some(Cow::Borrowed(content_line)),
474487
Mapping {
475488
generated_line: line as u32,
476489
generated_column: ((mapping.generated_column as i64)
@@ -581,7 +594,10 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
581594
let chunk_slice = if chunk_pos == 0 {
582595
chunk
583596
} else {
584-
Cow::Owned(chunk[chunk_pos as usize..].to_string())
597+
match chunk {
598+
Cow::Borrowed(c) => Cow::Borrowed(&c[chunk_pos as usize..]),
599+
Cow::Owned(c) => Cow::Owned(c[chunk_pos as usize..].to_string()),
600+
}
585601
};
586602
let line = mapping.generated_line as i64 + generated_line_offset;
587603
on_chunk(

0 commit comments

Comments
 (0)