Skip to content

Commit 7220862

Browse files
committed
perf: ReplaceSourceChunks by unsafe
1 parent 3c1808d commit 7220862

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

src/replace_source.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ impl<'a> ReplaceSourceChunks<'a> {
422422
}
423423

424424
impl Chunks for ReplaceSourceChunks<'_> {
425+
#[allow(unsafe_code)]
425426
fn stream<'a>(
426427
&'a self,
427428
object_pool: &'a ObjectPool,
@@ -541,14 +542,16 @@ impl Chunks for ReplaceSourceChunks<'_> {
541542
original.source_index,
542543
original.original_line,
543544
original.original_column,
544-
&chunk[0..chunk_pos as usize],
545+
unsafe { chunk.get_unchecked(..chunk_pos as usize) },
545546
)
546547
}) {
547548
original.original_column += chunk_pos;
548549
}
549550
pos += chunk_pos;
550551
let chunk_utf16_pos =
551-
chunk[..chunk_pos as usize].encode_utf16().count();
552+
unsafe { chunk.get_unchecked(..chunk_pos as usize) }
553+
.encode_utf16()
554+
.count();
552555
let line = mapping.generated_line as i64 + generated_line_offset;
553556
if generated_column_offset_line == line {
554557
generated_column_offset -= chunk_utf16_pos as i64;
@@ -567,8 +570,11 @@ impl Chunks for ReplaceSourceChunks<'_> {
567570
if next_replacement_pos > pos {
568571
// Emit chunk until replacement
569572
let offset = next_replacement_pos - pos;
570-
let chunk_slice =
571-
&chunk[chunk_pos as usize..(chunk_pos + offset) as usize];
573+
let chunk_slice = unsafe {
574+
chunk.get_unchecked(
575+
chunk_pos as usize..(chunk_pos + offset) as usize,
576+
)
577+
};
572578
let utf8_offset = chunk_slice.encode_utf16().count() as u32;
573579
on_chunk(
574580
Some(chunk_slice),
@@ -610,9 +616,7 @@ impl Chunks for ReplaceSourceChunks<'_> {
610616
}
611617
}
612618
// Insert replacement content split into chunks by lines
613-
#[allow(unsafe_code)]
614-
// SAFETY: The safety of this operation relies on the fact that the `ReplaceSource` type will not delete the `replacements` during its entire lifetime.
615-
let repl = &repls[i];
619+
let repl = unsafe { repls.get_unchecked(i) };
616620

617621
let lines =
618622
split_into_lines(repl.content.as_str()).collect::<Vec<_>>();
@@ -683,11 +687,7 @@ impl Chunks for ReplaceSourceChunks<'_> {
683687

684688
// Move to next replacement
685689
i += 1;
686-
next_replacement = if i < repls.len() {
687-
Some(repls[i].start)
688-
} else {
689-
None
690-
};
690+
next_replacement = self.replacements.get(i).map(|repl| repl.start);
691691

692692
// Skip over when it has been replaced
693693
let offset = chunk.len() as i64 - end_pos as i64
@@ -707,11 +707,15 @@ impl Chunks for ReplaceSourceChunks<'_> {
707707
}
708708
} else if generated_column_offset_line == line {
709709
let remaining_chunk_utf16_len =
710-
chunk[chunk_pos as usize..].encode_utf16().count() as i64;
710+
unsafe { chunk.get_unchecked(chunk_pos as usize..) }
711+
.encode_utf16()
712+
.count() as i64;
711713
generated_column_offset -= remaining_chunk_utf16_len;
712714
} else {
713715
generated_column_offset =
714-
-(chunk[chunk_pos as usize..].encode_utf16().count() as i64);
716+
-(unsafe { chunk.get_unchecked(chunk_pos as usize..) }
717+
.encode_utf16()
718+
.count() as i64);
715719
generated_column_offset_line = line;
716720
}
717721
pos = end_pos;
@@ -726,18 +730,24 @@ impl Chunks for ReplaceSourceChunks<'_> {
726730
original.source_index,
727731
original.original_line,
728732
original.original_column,
729-
&chunk
730-
[chunk_pos as usize..(chunk_pos + offset as u32) as usize],
733+
unsafe {
734+
chunk.get_unchecked(
735+
chunk_pos as usize..(chunk_pos + offset as u32) as usize,
736+
)
737+
},
731738
)
732739
})
733740
{
734741
original.original_column += offset as u32;
735742
}
736743

737-
let utf16_offset = chunk
738-
[chunk_pos as usize..(chunk_pos + offset as u32) as usize]
739-
.encode_utf16()
740-
.count() as i64;
744+
let utf16_offset = unsafe {
745+
chunk.get_unchecked(
746+
chunk_pos as usize..(chunk_pos + offset as u32) as usize,
747+
)
748+
}
749+
.encode_utf16()
750+
.count() as i64;
741751
chunk_pos += offset as u32;
742752
pos += offset as u32;
743753

@@ -809,7 +819,7 @@ impl Chunks for ReplaceSourceChunks<'_> {
809819
// Handle remaining replacements one by one
810820
let mut line = result.generated_line as i64 + generated_line_offset;
811821
while i < repls.len() {
812-
let content = &repls[i].content;
822+
let content = &unsafe { repls.get_unchecked(i) }.content;
813823
let lines: Vec<&str> = split_into_lines(content).collect();
814824

815825
for (line_idx, content_line) in lines.iter().enumerate() {

0 commit comments

Comments
 (0)