mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
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:
parent
df2dd3394e
commit
9fbacbfd19
1 changed files with 27 additions and 20 deletions
|
@ -71,8 +71,8 @@ trait DiffTrait {
|
||||||
|
|
||||||
fn to_tokens(&self) -> DiffTokens {
|
fn to_tokens(&self) -> DiffTokens {
|
||||||
let mut matcher = SequenceMatcher::new(self.get_typed(), self.get_expected());
|
let mut matcher = SequenceMatcher::new(self.get_typed(), self.get_expected());
|
||||||
let mut typed_tokens = Vec::new();
|
let mut typed_tokens = Vec::with_capacity(self.get_typed().len());
|
||||||
let mut expected_tokens = Vec::new();
|
let mut expected_tokens = Vec::with_capacity(self.get_expected().len());
|
||||||
|
|
||||||
for opcode in matcher.get_opcodes() {
|
for opcode in matcher.get_opcodes() {
|
||||||
let typed_slice = slice(self.get_typed(), opcode.first_start, opcode.first_end);
|
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
|
// Render Functions
|
||||||
fn render_tokens(tokens: &[DiffToken]) -> String {
|
fn render_tokens(tokens: &[DiffToken]) -> String {
|
||||||
tokens.iter().fold(String::new(), |mut acc, token| {
|
tokens.iter().fold(
|
||||||
let isolated_text = isolate_leading_mark(&token.text);
|
String::with_capacity(tokens.len() * 20),
|
||||||
let encoded_text = htmlescape::encode_minimal(&isolated_text);
|
|mut acc, token| {
|
||||||
let class = token.to_class();
|
let isolated_text = isolate_leading_mark(&token.text);
|
||||||
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
|
let encoded_text = htmlescape::encode_minimal(&isolated_text);
|
||||||
acc
|
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
|
/// 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 {
|
fn new(expected: &str, typed: &str) -> Self {
|
||||||
// filter out combining elements
|
// 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
|
// 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) {
|
for c in normalize(&prepare_expected(expected), true) {
|
||||||
if unicode_normalization::char::is_combining_mark(c) {
|
if unicode_normalization::char::is_combining_mark(c) {
|
||||||
if let Some(last) = expected_split.last_mut() {
|
if let Some(last) = expected_split.last_mut() {
|
||||||
|
@ -233,15 +237,18 @@ impl DiffTrait for DiffNonCombining {
|
||||||
// having to otherwise e.g. include their field twice in the note template.
|
// having to otherwise e.g. include their field twice in the note template.
|
||||||
fn render_expected_tokens(&self, tokens: &[DiffToken]) -> String {
|
fn render_expected_tokens(&self, tokens: &[DiffToken]) -> String {
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
tokens.iter().fold(String::new(), |mut acc, token| {
|
tokens.iter().fold(
|
||||||
let end = idx + token.text.chars().count();
|
String::with_capacity(tokens.len() * 20),
|
||||||
let txt = self.expected_split[idx..end].concat();
|
|mut acc, token| {
|
||||||
idx = end;
|
let end = idx + token.text.chars().count();
|
||||||
let encoded_text = htmlescape::encode_minimal(&txt);
|
let txt = self.expected_split[idx..end].concat();
|
||||||
let class = token.to_class();
|
idx = end;
|
||||||
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
|
let encoded_text = htmlescape::encode_minimal(&txt);
|
||||||
acc
|
let class = token.to_class();
|
||||||
})
|
acc.push_str(&format!("<span class={class}>{encoded_text}</span>"));
|
||||||
|
acc
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue