mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
perf: reduce allocations in CCSeq.to_array
This commit is contained in:
parent
2a1c7cd8f0
commit
45f567dca1
1 changed files with 4 additions and 3 deletions
|
|
@ -414,16 +414,17 @@ let of_string s =
|
||||||
|
|
||||||
let to_array l =
|
let to_array l =
|
||||||
(* We contruct the length and list of seq elements (in reverse) in one pass *)
|
(* 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
|
(* 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
|
each item, working back from the last. This lets us only traverse the list
|
||||||
twice, instead of having to reverse it. *)
|
twice, instead of having to reverse it. *)
|
||||||
match ls with
|
match ls with
|
||||||
| [] -> [||]
|
| [] -> [||]
|
||||||
| init::rest ->
|
| 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] *)
|
(* 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);
|
ignore (List.fold_left (fun i x -> a.(i) <- x; i - 1) idx rest : int);
|
||||||
a
|
a
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue