From c63c67ad7efb6e7a631ea43182b4685bdcf9880e Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Mon, 9 Nov 2026 14:40:26 +0000 Subject: [PATCH] Visit an arrow's argument types without a closure Why: `iter_type_expr` visited the argument types of a `Tarrow` with `List.iter (fun {typ} -> f typ)`, which allocates a closure each time it reaches an arrow type. Many walks over types go through it (copying, marking, levels, occur checks), and function types are common. The arguments are now visited by a recursive function that takes `f`. The order of the visits is unchanged. Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -0.22% in total (-0.20% for the files compiled one by one, -0.24% in the builds of tests/tests), stress/NestedClosures.res -0.89%. On a 552 module React app (clean build, one domain) the build allocates 0.18% fewer words. Signed-off-by: Jono Prest --- changes/iter-arg-types.polish.md | 1 + compiler/ml/btype.ml | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 changes/iter-arg-types.polish.md diff --git a/changes/iter-arg-types.polish.md b/changes/iter-arg-types.polish.md new file mode 100644 index 0000000000..ca7c922a42 --- /dev/null +++ b/changes/iter-arg-types.polish.md @@ -0,0 +1 @@ +- Walk the parameters of a function type without allocating a closure, so the compiler allocates about 0.2% less. diff --git a/compiler/ml/btype.ml b/compiler/ml/btype.ml index 90a09c42a1..7bd6f9f611 100644 --- a/compiler/ml/btype.ml +++ b/compiler/ml/btype.ml @@ -240,11 +240,18 @@ let rec iter_row f row = Misc.may (fun (_, l) -> List.iter f l) row.row_name | _ -> assert false +(* Not [List.iter] with a closure, which would be allocated at every arrow. *) +let rec iter_arg_types f = function + | [] -> () + | {typ} :: params -> + f typ; + iter_arg_types f params + let iter_type_expr f ty = match ty.desc with | Tvar _ -> () | Tarrow (params, ret) -> - List.iter (fun {typ} -> f typ) params; + iter_arg_types f params; f ret | Ttuple l -> List.iter f l | Tconstr (_, l, _) -> List.iter f l