typeanswer: micro-optimize vectors

Should get rid of most relocations, at the expense of over-allocating.

On Vec's (String's) behavior: https://stackoverflow.com/a/72787776
This commit is contained in:
Andreas Reis 2024-09-30 01:28:38 +02:00
parent df2dd3394e
commit 9fbacbfd19

View file

@ -71,8 +71,8 @@ trait DiffTrait {
fn to_tokens(&self) -> DiffTokens {
let mut matcher = SequenceMatcher::new(self.get_typed(), self.get_expected());
let mut typed_tokens = Vec::new();
let mut expected_tokens = Vec::new();
let mut typed_tokens = Vec::with_capacity(self.get_typed().len());
let mut expected_tokens = Vec::with_capacity(self.get_expected().len());
for opcode in matcher.get_opcodes() {
let typed_slice = slice(self.get_typed(), opcode.first_start, opcode.first_end);
@ -132,13 +132,16 @@ fn prepare_expected(expected: &str) -> String {
// Render Functions
fn render_tokens(tokens: &[DiffToken]) -> String {
tokens.iter().fold(String::new(), |mut acc, token| {
tokens.iter().fold(
String::with_capacity(tokens.len() * 20),
|mut acc, token| {
let isolated_text = isolate_leading_mark(&token.text);
let encoded_text = htmlescape::encode_minimal(&isolated_text);
let class = token.to_class();
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
acc
})
},
)
}
/// Prefixes a leading mark character with a non-breaking space to prevent
@ -204,9 +207,10 @@ impl DiffTrait for DiffNonCombining {
fn new(expected: &str, typed: &str) -> Self {
// filter out combining elements
let mut expected_stripped = String::new();
let mut expected_stripped = String::with_capacity(expected.len());
// tokenized into "char+combining" for final rendering
let mut expected_split: Vec<String> = Vec::new();
let mut expected_split: Vec<String> = Vec::with_capacity(expected.len());
for c in normalize(&prepare_expected(expected), true) {
if unicode_normalization::char::is_combining_mark(c) {
if let Some(last) = expected_split.last_mut() {
@ -233,7 +237,9 @@ impl DiffTrait for DiffNonCombining {
// having to otherwise e.g. include their field twice in the note template.
fn render_expected_tokens(&self, tokens: &[DiffToken]) -> String {
let mut idx = 0;
tokens.iter().fold(String::new(), |mut acc, token| {
tokens.iter().fold(
String::with_capacity(tokens.len() * 20),
|mut acc, token| {
let end = idx + token.text.chars().count();
let txt = self.expected_split[idx..end].concat();
idx = end;
@ -241,7 +247,8 @@ impl DiffTrait for DiffNonCombining {
let class = token.to_class();
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
acc
})
},
)
}
}