Skip to content

Commit

Permalink
typeanswer: micro-optimize vectors
Browse files Browse the repository at this point in the history
Should get rid of most relocations, at the expense of over-allocating.

On Vec's (String's) behavior: https://stackoverflow.com/a/72787776
  • Loading branch information
twwn committed Sep 27, 2024
1 parent d6734bf commit 32132e7
Showing 1 changed file with 27 additions and 20 deletions.
47 changes: 27 additions & 20 deletions rslib/src/typeanswer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ trait DiffTrait {

fn to_tokens(&self) -> DiffTokens {
let mut matcher = SequenceMatcher::new(self.get_provided(), self.get_expected());
let mut provided_tokens = Vec::new();
let mut expected_tokens = Vec::new();
let mut provided_tokens = Vec::with_capacity(self.get_provided().len());
let mut expected_tokens = Vec::with_capacity(self.get_expected().len());

for opcode in matcher.get_opcodes() {
let provided_slice = slice(&self.get_provided(), opcode.first_start, opcode.first_end);
Expand Down Expand Up @@ -133,13 +133,16 @@ fn prepare_expected(expected: &str) -> String {

// Render Functions
fn render_tokens(tokens: &[DiffToken]) -> String {
tokens.iter().fold(String::new(), |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
})
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
Expand Down Expand Up @@ -206,9 +209,10 @@ impl DiffTrait for DiffNonCombining {

fn new(expected: &str, provided: &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() {
Expand All @@ -235,15 +239,18 @@ 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| {
let end = idx + token.text.chars().count();
let txt = self.expected_split[idx..end].concat();
idx = end;
let encoded_text = htmlescape::encode_minimal(&txt);
let class = token.to_class();
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
acc
})
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;
let encoded_text = htmlescape::encode_minimal(&txt);
let class = token.to_class();
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
acc
},
)
}
}

Expand Down

0 comments on commit 32132e7

Please sign in to comment.