From 22fb31198a43482d0a61c3b0cc8c42fc55decf3c Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 19 Nov 2021 19:21:26 +0100 Subject: [PATCH] use bumpalo to reduce allocations in deep_copy_var_to --- Cargo.lock | 1 + compiler/types/Cargo.toml | 1 + compiler/types/src/subs.rs | 65 ++++++++++++++++++++++---------------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebbca7c3e8..1260b2fec3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3554,6 +3554,7 @@ version = "0.1.0" name = "roc_types" version = "0.1.0" dependencies = [ + "bumpalo", "roc_collections", "roc_module", "roc_region", diff --git a/compiler/types/Cargo.toml b/compiler/types/Cargo.toml index a47245bf95..97cd23ac45 100644 --- a/compiler/types/Cargo.toml +++ b/compiler/types/Cargo.toml @@ -10,4 +10,5 @@ roc_collections = { path = "../collections" } roc_region = { path = "../region" } roc_module = { path = "../module" } ven_ena = { path = "../../vendor/ena" } +bumpalo = { version = "3.8.0", features = ["collections"] } static_assertions = "1.1.0" diff --git a/compiler/types/src/subs.rs b/compiler/types/src/subs.rs index a4200c88e9..f91c6c6807 100644 --- a/compiler/types/src/subs.rs +++ b/compiler/types/src/subs.rs @@ -3030,20 +3030,24 @@ pub fn deep_copy_var_to( ) -> Variable { 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); copy } -fn deep_copy_var_to_help( - // source: &mut Subs, // mut to set the copy +fn deep_copy_var_to_help<'a>( + arena: &'a bumpalo::Bump, source: &mut Subs, target: &mut Subs, max_rank: Rank, var: Variable, ) -> Variable { + use bumpalo::collections::Vec; use Content::*; use FlatType::*; @@ -3087,30 +3091,30 @@ fn deep_copy_var_to_help( Structure(flat_type) => { let new_flat_type = match flat_type { 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() { let var = source[index]; - let copy_var = deep_copy_var_to_help(source, target, max_rank, var); - new_arg_vars.push(copy_var); + new_args.push(deep_copy_var_to_help(arena, source, target, max_rank, 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) } 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 = - 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() { 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); } @@ -3123,11 +3127,12 @@ fn deep_copy_var_to_help( Record(fields, ext_var) => { 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() { 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); } @@ -3158,21 +3163,22 @@ fn deep_copy_var_to_help( Record( 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) => { - 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() { let slice = source[index]; for var_index in slice { 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); } @@ -3216,19 +3222,20 @@ fn deep_copy_var_to_help( FunctionOrTagUnion( new_tag_name, 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) => { - 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() { let slice = source[index]; for var_index in slice { 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); } @@ -3261,8 +3268,9 @@ fn deep_copy_var_to_help( 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_rec_var = deep_copy_var_to_help(source, target, max_rank, rec_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(arena, source, target, max_rank, rec_var); RecursiveTagUnion(new_rec_var, union_tags, new_ext) } @@ -3279,7 +3287,7 @@ fn deep_copy_var_to_help( opt_name, 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()); @@ -3301,11 +3309,11 @@ fn deep_copy_var_to_help( } 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() { 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); } @@ -3318,7 +3326,8 @@ fn deep_copy_var_to_help( args.lowercases_start = target.field_names.len() as u32; 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); target.set(copy, make_descriptor(new_content));