Skip to content

Commit

Permalink
perf: pre-allocate text change string capacity (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret authored Dec 29, 2024
1 parent 3aba071 commit 4b90da4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 28 deletions.
14 changes: 12 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ swc_visit = { version = "=0.6.2", optional = true }
swc_visit_macros = { version = "=0.5.13", optional = true }
# just for error handling
sourcemap = { version = "9.0.0", optional = true }
string_capacity = "0.1.4"
thiserror = "2"

[dev-dependencies]
Expand Down
52 changes: 26 additions & 26 deletions src/text_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use std::cmp::Ordering;
use std::ops::Range;

use string_capacity::StringBuilder;

#[derive(Clone, Debug)]
pub struct TextChange {
/// Range start to end byte index.
Expand Down Expand Up @@ -30,34 +32,32 @@ pub fn apply_text_changes(
ordering => ordering,
});

let mut last_index = 0;
let mut final_text = String::new();

for (i, change) in changes.iter().enumerate() {
if change.range.start > change.range.end {
panic!(
"Text change had start index {} greater than end index {}.\n\n{:?}",
change.range.start,
change.range.end,
&changes[0..i + 1],
)
}
if change.range.start < last_index {
panic!("Text changes were overlapping. Past index was {}, but new change had index {}.\n\n{:?}", last_index, change.range.start, &changes[0..i + 1]);
} else if change.range.start > last_index && last_index < source.len() {
final_text.push_str(
&source[last_index..std::cmp::min(source.len(), change.range.start)],
);
StringBuilder::build(|builder| {
let mut last_index = 0;
for (i, change) in changes.iter().enumerate() {
if change.range.start > change.range.end {
panic!(
"Text change had start index {} greater than end index {}.\n\n{:?}",
change.range.start,
change.range.end,
&changes[0..i + 1],
)
}
if change.range.start < last_index {
panic!("Text changes were overlapping. Past index was {}, but new change had index {}.\n\n{:?}", last_index, change.range.start, &changes[0..i + 1]);
} else if change.range.start > last_index && last_index < source.len() {
builder.append(
&source[last_index..std::cmp::min(source.len(), change.range.start)],
);
}
builder.append(&change.new_text);
last_index = change.range.end;
}
final_text.push_str(&change.new_text);
last_index = change.range.end;
}

if last_index < source.len() {
final_text.push_str(&source[last_index..]);
}

final_text
if last_index < source.len() {
builder.append(&source[last_index..]);
}
}).unwrap()
}

#[cfg(test)]
Expand Down

0 comments on commit 4b90da4

Please sign in to comment.