Skip to content

Commit

Permalink
[unionfind] fewer allocations
Browse files Browse the repository at this point in the history
Summary:
Simplify and remove most allocations from `UnionFind.find` by using exceptions and looping instead of options and recursion.

In a test target this leads to about 600 fewer minor collections (over a baseline of 5800). memtrace (after backporting to 4.14) shows a much bigger reduction of total allocations (from 20B to 18B) and a complete disappearance of `UnionFind.find/find_opt` from the top 10 allocators (it was 3rd).

Reviewed By: davidpichardie

Differential Revision:
D69612368

Privacy Context Container: L1208441

fbshipit-source-id: e7e17b87b7bda99becc0df40f7283c5f0372a8d4
  • Loading branch information
ngorogiannis authored and facebook-github-bot committed Feb 14, 2025
1 parent 32c9aad commit 921549d
Showing 1 changed file with 10 additions and 14 deletions.
24 changes: 10 additions & 14 deletions infer/src/istd/UnionFind.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,17 @@ struct

let is_empty = XMap.is_empty

let find_opt reprs x =
let rec find_opt_aux candidate_repr =
(* [x] is in the relation and now we are climbing up to the final representative *)
match XMap.find_opt candidate_repr reprs with
| None ->
(* [candidate_repr] is the representative *)
candidate_repr
| Some candidate_repr' ->
(* keep climbing *)
find_opt_aux candidate_repr'
in
XMap.find_opt x reprs |> Option.map ~f:find_opt_aux

let find reprs x =
let r = ref x in
try
while true do
(* [x] is in the relation and now we are climbing up to the final representative *)
r := XMap.find !r reprs
done ;
(* never happens *)
x
with Stdlib.Not_found -> !r

let find reprs x = find_opt reprs x |> Option.value ~default:x

let merge reprs x ~into:y = (* TODO: implement path compression *) XMap.add x y reprs

Expand Down

0 comments on commit 921549d

Please sign in to comment.