use bumpalo to reduce allocations in deep_copy_var_to

This commit is contained in:
Folkert 2021-11-19 19:21:26 +01:00
parent 2fe8537177
commit 22fb31198a
3 changed files with 39 additions and 28 deletions

1
Cargo.lock generated
View file

@ -3554,6 +3554,7 @@ version = "0.1.0"
name = "roc_types" name = "roc_types"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bumpalo",
"roc_collections", "roc_collections",
"roc_module", "roc_module",
"roc_region", "roc_region",

View file

@ -10,4 +10,5 @@ roc_collections = { path = "../collections" }
roc_region = { path = "../region" } roc_region = { path = "../region" }
roc_module = { path = "../module" } roc_module = { path = "../module" }
ven_ena = { path = "../../vendor/ena" } ven_ena = { path = "../../vendor/ena" }
bumpalo = { version = "3.8.0", features = ["collections"] }
static_assertions = "1.1.0" static_assertions = "1.1.0"

View file

@ -3030,20 +3030,24 @@ pub fn deep_copy_var_to(
) -> Variable { ) -> Variable {
let rank = Rank::toplevel(); let rank = Rank::toplevel();
let copy = deep_copy_var_to_help(source, target, rank, var); // capacity based on the false hello world program
let arena = bumpalo::Bump::with_capacity(4 * 1024);
let copy = deep_copy_var_to_help(&arena, source, target, rank, var);
source.restore(var); source.restore(var);
copy copy
} }
fn deep_copy_var_to_help( fn deep_copy_var_to_help<'a>(
// source: &mut Subs, // mut to set the copy arena: &'a bumpalo::Bump,
source: &mut Subs, source: &mut Subs,
target: &mut Subs, target: &mut Subs,
max_rank: Rank, max_rank: Rank,
var: Variable, var: Variable,
) -> Variable { ) -> Variable {
use bumpalo::collections::Vec;
use Content::*; use Content::*;
use FlatType::*; use FlatType::*;
@ -3087,30 +3091,30 @@ fn deep_copy_var_to_help(
Structure(flat_type) => { Structure(flat_type) => {
let new_flat_type = match flat_type { let new_flat_type = match flat_type {
Apply(symbol, args) => { Apply(symbol, args) => {
let mut new_arg_vars = Vec::with_capacity(args.len()); let mut new_args = Vec::with_capacity_in(args.len(), arena);
for index in args.into_iter() { for index in args.into_iter() {
let var = source[index]; let var = source[index];
let copy_var = deep_copy_var_to_help(source, target, max_rank, var); new_args.push(deep_copy_var_to_help(arena, source, target, max_rank, var));
new_arg_vars.push(copy_var);
} }
let arg_vars = VariableSubsSlice::insert_into_subs(target, new_arg_vars); let arg_vars = VariableSubsSlice::insert_into_subs(target, new_args);
Apply(symbol, arg_vars) Apply(symbol, arg_vars)
} }
Func(arg_vars, closure_var, ret_var) => { Func(arg_vars, closure_var, ret_var) => {
let new_ret_var = deep_copy_var_to_help(source, target, max_rank, ret_var); let new_ret_var =
deep_copy_var_to_help(arena, source, target, max_rank, ret_var);
let new_closure_var = let new_closure_var =
deep_copy_var_to_help(source, target, max_rank, closure_var); deep_copy_var_to_help(arena, source, target, max_rank, closure_var);
let mut new_arg_vars = Vec::with_capacity(arg_vars.len()); let mut new_arg_vars = Vec::with_capacity_in(arg_vars.len(), arena);
for index in arg_vars.into_iter() { for index in arg_vars.into_iter() {
let var = source[index]; let var = source[index];
let copy_var = deep_copy_var_to_help(source, target, max_rank, var); let copy_var = deep_copy_var_to_help(arena, source, target, max_rank, var);
new_arg_vars.push(copy_var); new_arg_vars.push(copy_var);
} }
@ -3123,11 +3127,12 @@ fn deep_copy_var_to_help(
Record(fields, ext_var) => { Record(fields, ext_var) => {
let record_fields = { let record_fields = {
let mut new_vars = Vec::with_capacity(fields.len()); let mut new_vars = Vec::with_capacity_in(fields.len(), arena);
for index in fields.iter_variables() { for index in fields.iter_variables() {
let var = source[index]; let var = source[index];
let copy_var = deep_copy_var_to_help(source, target, max_rank, var); let copy_var =
deep_copy_var_to_help(arena, source, target, max_rank, var);
new_vars.push(copy_var); new_vars.push(copy_var);
} }
@ -3158,21 +3163,22 @@ fn deep_copy_var_to_help(
Record( Record(
record_fields, record_fields,
deep_copy_var_to_help(source, target, max_rank, ext_var), deep_copy_var_to_help(arena, source, target, max_rank, ext_var),
) )
} }
TagUnion(tags, ext_var) => { TagUnion(tags, ext_var) => {
let new_ext = deep_copy_var_to_help(source, target, max_rank, ext_var); let new_ext = deep_copy_var_to_help(arena, source, target, max_rank, ext_var);
let mut new_variable_slices = Vec::with_capacity(tags.len()); let mut new_variable_slices = Vec::with_capacity_in(tags.len(), arena);
let mut new_variables = Vec::new(); let mut new_variables = Vec::with_capacity_in(tags.len(), arena);
for index in tags.variables() { for index in tags.variables() {
let slice = source[index]; let slice = source[index];
for var_index in slice { for var_index in slice {
let var = source[var_index]; let var = source[var_index];
let new_var = deep_copy_var_to_help(source, target, max_rank, var); let new_var =
deep_copy_var_to_help(arena, source, target, max_rank, var);
new_variables.push(new_var); new_variables.push(new_var);
} }
@ -3216,19 +3222,20 @@ fn deep_copy_var_to_help(
FunctionOrTagUnion( FunctionOrTagUnion(
new_tag_name, new_tag_name,
symbol, symbol,
deep_copy_var_to_help(source, target, max_rank, ext_var), deep_copy_var_to_help(arena, source, target, max_rank, ext_var),
) )
} }
RecursiveTagUnion(rec_var, tags, ext_var) => { RecursiveTagUnion(rec_var, tags, ext_var) => {
let mut new_variable_slices = Vec::with_capacity(tags.len()); let mut new_variable_slices = Vec::with_capacity_in(tags.len(), arena);
let mut new_variables = Vec::new(); let mut new_variables = Vec::with_capacity_in(tags.len(), arena);
for index in tags.variables() { for index in tags.variables() {
let slice = source[index]; let slice = source[index];
for var_index in slice { for var_index in slice {
let var = source[var_index]; let var = source[var_index];
let new_var = deep_copy_var_to_help(source, target, max_rank, var); let new_var =
deep_copy_var_to_help(arena, source, target, max_rank, var);
new_variables.push(new_var); new_variables.push(new_var);
} }
@ -3261,8 +3268,9 @@ fn deep_copy_var_to_help(
let union_tags = UnionTags::from_slices(new_tag_names, new_variables); let union_tags = UnionTags::from_slices(new_tag_names, new_variables);
let new_ext = deep_copy_var_to_help(source, target, max_rank, ext_var); let new_ext = deep_copy_var_to_help(arena, source, target, max_rank, ext_var);
let new_rec_var = deep_copy_var_to_help(source, target, max_rank, rec_var); let new_rec_var =
deep_copy_var_to_help(arena, source, target, max_rank, rec_var);
RecursiveTagUnion(new_rec_var, union_tags, new_ext) RecursiveTagUnion(new_rec_var, union_tags, new_ext)
} }
@ -3279,7 +3287,7 @@ fn deep_copy_var_to_help(
opt_name, opt_name,
structure, structure,
} => { } => {
let new_structure = deep_copy_var_to_help(source, target, max_rank, structure); let new_structure = deep_copy_var_to_help(arena, source, target, max_rank, structure);
debug_assert!((new_structure.index() as usize) < target.len()); debug_assert!((new_structure.index() as usize) < target.len());
@ -3301,11 +3309,11 @@ fn deep_copy_var_to_help(
} }
Alias(symbol, mut args, real_type_var) => { Alias(symbol, mut args, real_type_var) => {
let mut new_vars = Vec::with_capacity(args.variables().len()); let mut new_vars = Vec::with_capacity_in(args.variables().len(), arena);
for var_index in args.variables() { for var_index in args.variables() {
let var = source[var_index]; let var = source[var_index];
let new_var = deep_copy_var_to_help(source, target, max_rank, var); let new_var = deep_copy_var_to_help(arena, source, target, max_rank, var);
new_vars.push(new_var); new_vars.push(new_var);
} }
@ -3318,7 +3326,8 @@ fn deep_copy_var_to_help(
args.lowercases_start = target.field_names.len() as u32; args.lowercases_start = target.field_names.len() as u32;
target.field_names.extend(lowercases.iter().cloned()); target.field_names.extend(lowercases.iter().cloned());
let new_real_type_var = deep_copy_var_to_help(source, target, max_rank, real_type_var); let new_real_type_var =
deep_copy_var_to_help(arena, source, target, max_rank, real_type_var);
let new_content = Alias(symbol, args, new_real_type_var); let new_content = Alias(symbol, args, new_real_type_var);
target.set(copy, make_descriptor(new_content)); target.set(copy, make_descriptor(new_content));