From 45f567dca17608cfb1f3035959e03e655cddcde0 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Fri, 11 Feb 2022 21:15:09 -0500 Subject: [PATCH] perf: reduce allocations in CCSeq.to_array --- src/core/CCSeq.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/CCSeq.ml b/src/core/CCSeq.ml index 5cf9d55b..b911caeb 100644 --- a/src/core/CCSeq.ml +++ b/src/core/CCSeq.ml @@ -414,16 +414,17 @@ let of_string s = let to_array l = (* We contruct the length and list of seq elements (in reverse) in one pass *) - let len, ls = fold_left (fun (i, acc) x -> (i + 1, x :: acc)) (0, []) l in + let len = ref 0 in + let ls = fold_left (fun acc x -> incr len; x :: acc) [] l in (* The length is used to initialize the array, and then to derive the index for each item, working back from the last. This lets us only traverse the list twice, instead of having to reverse it. *) match ls with | [] -> [||] | init::rest -> - let a = Array.make len init in + let a = Array.make !len init in (* Subtract 1 for len->index conversion and 1 for the removed [init] *) - let idx = len - 2 in + let idx = !len - 2 in ignore (List.fold_left (fun i x -> a.(i) <- x; i - 1) idx rest : int); a