perf: tweaks in CCVector

This commit is contained in:
Simon Cruanes 2018-07-25 14:31:08 -05:00
parent 551c837398
commit c800250038

View file

@ -87,11 +87,11 @@ let resize_ v newcapacity =
(* grow the array, using [x] as a filler if required *) (* grow the array, using [x] as a filler if required *)
let grow_with_ v ~filler:x = let grow_with_ v ~filler:x =
if array_is_empty_ v if array_is_empty_ v then (
then v.vec <- Array.make 32 x v.vec <- Array.make 4 x
else ( ) else (
let n = Array.length v.vec in let n = Array.length v.vec in
let size = min (2 * n + 10) Sys.max_array_length in let size = min (2 * n + 3) Sys.max_array_length in
if size = n then failwith "vec: can't grow any further"; if size = n then failwith "vec: can't grow any further";
resize_ v size resize_ v size
) )
@ -104,20 +104,22 @@ let ensure_assuming_not_empty_ v ~size =
if size > Sys.max_array_length if size > Sys.max_array_length
then failwith "vec.ensure: size too big" then failwith "vec.ensure: size too big"
else ( else (
let n = ref (max 16 (Array.length v.vec)) in let n = ref (max 8 (Array.length v.vec)) in
while !n < size do n := min Sys.max_array_length (2* !n) done; while !n < size do n := min Sys.max_array_length (2* !n) done;
resize_ v !n resize_ v !n
) )
let ensure_with ~init v size = let ensure_with ~init v size =
if Array.length v.vec = 0 if Array.length v.vec = 0 then (
then v.vec <- Array.make size init v.vec <- Array.make size init
else ensure_assuming_not_empty_ v ~size ) else (
ensure_assuming_not_empty_ v ~size
)
let ensure v size = let ensure v size =
if Array.length v.vec = 0 if Array.length v.vec > 0 then (
then () ensure_assuming_not_empty_ v ~size
else ensure_assuming_not_empty_ v ~size )
let clear v = let clear v =
v.size <- 0 v.size <- 0
@ -452,12 +454,14 @@ let uniq_sort cmp v =
*) *)
let iter k v = let iter k v =
for i = 0 to v.size -1 do let n = v.size in
for i = 0 to n-1 do
k (Array.unsafe_get v.vec i) k (Array.unsafe_get v.vec i)
done done
let iteri k v = let iteri k v =
for i = 0 to v.size -1 do let n = v.size in
for i = 0 to n-1 do
k i (Array.unsafe_get v.vec i) k i (Array.unsafe_get v.vec i)
done done
@ -576,18 +580,24 @@ let for_all p v =
let member ~eq x v = let member ~eq x v =
exists (eq x) v exists (eq x) v
let find_exn p v = let find_internal_ p v =
let n = v.size in let n = v.size in
let rec check i = let rec check i =
if i = n then raise Not_found if i = n then raise_notrace Not_found
else else (
let x = v.vec.(i) in let x = v.vec.(i) in
if p x then x if p x then x
else check (i+1) else check (i+1)
)
in check 0 in check 0
let find_exn p v =
try find_internal_ p v
with Not_found ->
raise Not_found
let find p v = let find p v =
try Some (find_exn p v) try Some (find_internal_ p v)
with Not_found -> None with Not_found -> None
(*$QR (*$QR
@ -693,8 +703,9 @@ let rev v =
*) *)
let rev_iter f v = let rev_iter f v =
for i = v.size-1 downto 0 do let n = v.size in
f v.vec.(i) for i = n-1 downto 0 do
f (Array.unsafe_get v.vec i)
done done
(*$T (*$T
@ -726,7 +737,8 @@ let of_seq ?(init=create ()) seq =
let to_seq v k = iter k v let to_seq v k = iter k v
let to_seq_rev v k = let to_seq_rev v k =
for i = v.size - 1 downto 0 do let n = v.size in
for i = n - 1 downto 0 do
k (Array.unsafe_get v.vec i) k (Array.unsafe_get v.vec i)
done done
@ -789,8 +801,10 @@ let of_array a =
let of_list l = match l with let of_list l = match l with
| [] -> create() | [] -> create()
| [x] -> return x
| [x;y] -> {size=2; vec=[| x; y |]}
| x::_ -> | x::_ ->
let v = create_with ~capacity:(List.length l + 5) x in let v = create_with ~capacity:(List.length l) x in
List.iter (push_unsafe_ v) l; List.iter (push_unsafe_ v) l;
v v