use insertion sort

This commit is contained in:
Folkert 2021-11-24 22:52:56 +01:00
parent 51c61ea449
commit 9c551a0276
2 changed files with 39 additions and 3 deletions

View file

@ -468,7 +468,7 @@ fn can_annotation_help(
// sort here; we later instantiate type aliases, so this type might get duplicated // sort here; we later instantiate type aliases, so this type might get duplicated
// many times. Then, when inserting into the subs, the tags are sorted. // many times. Then, when inserting into the subs, the tags are sorted.
// in theory we save a lot of time by sorting once here // in theory we save a lot of time by sorting once here
tag_types.sort_by(|a, b| a.0.cmp(&b.0)); insertion_sort_by(&mut tag_types, |a, b| a.0.cmp(&b.0));
Type::TagUnion(tag_types, Box::new(ext_type)) Type::TagUnion(tag_types, Box::new(ext_type))
} }
@ -508,6 +508,24 @@ fn can_annotation_help(
} }
} }
fn insertion_sort_by<T, F>(arr: &mut [T], mut compare: F)
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
for i in 1..arr.len() {
let val = &arr[i];
let mut j = i;
let pos = arr[..i]
.binary_search_by(|x| compare(x, val))
.unwrap_or_else(|pos| pos);
// Swap all elements until specific position.
while j > pos {
arr.swap(j - 1, j);
j -= 1;
}
}
}
// TODO trim down these arguments! // TODO trim down these arguments!
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn can_assigned_fields<'a>( fn can_assigned_fields<'a>(

View file

@ -742,7 +742,7 @@ fn type_to_variable<'a>(
.map(|(field, field_type)| (field.clone(), field_type)); .map(|(field, field_type)| (field.clone(), field_type));
field_vars.extend(it); field_vars.extend(it);
field_vars.sort_unstable_by(RecordFields::compare); insertion_sort_by(&mut field_vars, RecordFields::compare);
let record_fields = RecordFields::insert_into_subs(subs, field_vars); let record_fields = RecordFields::insert_into_subs(subs, field_vars);
@ -912,6 +912,24 @@ fn alias_to_var<'a>(
} }
} }
fn insertion_sort_by<T, F>(arr: &mut [T], mut compare: F)
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
for i in 1..arr.len() {
let val = &arr[i];
let mut j = i;
let pos = arr[..i]
.binary_search_by(|x| compare(x, val))
.unwrap_or_else(|pos| pos);
// Swap all elements until specific position.
while j > pos {
arr.swap(j - 1, j);
j -= 1;
}
}
}
fn sorted_no_duplicates<T>(slice: &[(TagName, T)]) -> bool { fn sorted_no_duplicates<T>(slice: &[(TagName, T)]) -> bool {
match slice.split_first() { match slice.split_first() {
None => true, None => true,
@ -932,7 +950,7 @@ fn sorted_no_duplicates<T>(slice: &[(TagName, T)]) -> bool {
} }
fn sort_and_deduplicate<T>(tag_vars: &mut bumpalo::collections::Vec<(TagName, T)>) { fn sort_and_deduplicate<T>(tag_vars: &mut bumpalo::collections::Vec<(TagName, T)>) {
tag_vars.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); insertion_sort_by(tag_vars, |(a, _), (b, _)| a.cmp(b));
// deduplicate, keeping the right-most occurrence of a tag name // deduplicate, keeping the right-most occurrence of a tag name
let mut i = 0; let mut i = 0;