Skip to content

Commit 7541318

Browse files
committed
fix: performance regression from #8447
Get rid of the slow dune file comparison in #9738 Signed-off-by: Rudi Grinberg <[email protected]> <!-- ps-id: 6499de7c-e597-44e0-af7f-33bf7bf235ab -->
1 parent c1f5466 commit 7541318

File tree

4 files changed

+53
-86
lines changed

4 files changed

+53
-86
lines changed

bin/describe/describe_pp.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ let get_pped_file super_context file =
5656
>>| Source_tree.Dir.path
5757
>>| Path.source
5858
in
59-
let* dune_file = Dune_rules.Dune_load.in_dir (dir |> in_build_dir) in
59+
let* dune_file = Dune_rules.Only_packages.stanzas_in_dir (dir |> in_build_dir) in
6060
let staged_pps =
6161
Option.bind dune_file ~f:(fun dune_file ->
6262
dune_file.stanzas

src/dune_rules/dune_load.ml

Lines changed: 21 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -215,42 +215,26 @@ module Dune_files = struct
215215

216216
type t = one list
217217

218-
let interpret =
219-
let impl (dir, project, dune_file) =
220-
let file = Source_tree.Dune_file.path dune_file in
221-
let static = Source_tree.Dune_file.get_static_sexp dune_file in
222-
match Source_tree.Dune_file.kind dune_file with
223-
| Ocaml_script ->
224-
Memo.return
225-
(Script
226-
{ script =
227-
{ dir
228-
; project
229-
; file =
230-
(* we can't introduce ocaml syntax with [(sudir ..)] *)
231-
Option.value_exn file
232-
}
233-
; from_parent = static
234-
})
235-
| Plain ->
236-
let open Memo.O in
237-
let+ stanzas = Dune_file.parse static ~dir ~file ~project in
238-
Literal stanzas
239-
in
240-
let module Input = struct
241-
type t = Path.Source.t * Dune_project.t * Source_tree.Dune_file.t
242-
243-
let equal =
244-
Tuple.T3.equal Path.Source.equal Dune_project.equal Source_tree.Dune_file.equal
245-
;;
246-
247-
let hash = Tuple.T3.hash Path.Source.hash Dune_project.hash Poly.hash
248-
let to_dyn = Dyn.opaque
249-
end
250-
in
251-
let memo = Memo.create "Dune_files.interpret" ~input:(module Input) impl in
252-
fun ~dir ~project ~(dune_file : Source_tree.Dune_file.t) ->
253-
Memo.exec memo (dir, project, dune_file)
218+
let interpret ~dir project dune_file =
219+
let file = Source_tree.Dune_file.path dune_file in
220+
let static = Source_tree.Dune_file.get_static_sexp dune_file in
221+
match Source_tree.Dune_file.kind dune_file with
222+
| Ocaml_script ->
223+
Memo.return
224+
(Script
225+
{ script =
226+
{ dir
227+
; project
228+
; file =
229+
(* we can't introduce ocaml syntax with [(sudir ..)] *)
230+
Option.value_exn file
231+
}
232+
; from_parent = static
233+
})
234+
| Plain ->
235+
let open Memo.O in
236+
let+ stanzas = Dune_file.parse static ~dir ~file ~project in
237+
Literal stanzas
254238
;;
255239

256240
let eval dune_files ~context =
@@ -328,7 +312,7 @@ let load () =
328312
let+ dune_files =
329313
Appendable_list.to_list dune_files
330314
|> Memo.parallel_map ~f:(fun (dir, project, dune_file) ->
331-
Dune_files.interpret ~dir ~project ~dune_file)
315+
Dune_files.interpret ~dir project dune_file)
332316
in
333317
{ dune_files
334318
; packages
@@ -339,34 +323,6 @@ let load () =
339323
}
340324
;;
341325

342-
let in_dir dir =
343-
let source_dir = Path.Build.drop_build_context_exn dir in
344-
Source_tree.find_dir source_dir
345-
>>= function
346-
| None -> Memo.return None
347-
| Some d ->
348-
(match Source_tree.Dir.dune_file d with
349-
| None -> Memo.return None
350-
| Some dune_file ->
351-
let project = Source_tree.Dir.project d in
352-
Dune_files.interpret ~dir:source_dir ~project ~dune_file
353-
>>= (function
354-
| Literal dune_file -> Memo.return (Some dune_file)
355-
| Script script ->
356-
let context =
357-
match Install.Context.of_path dir with
358-
| Some c -> c
359-
| None ->
360-
User_error.raise
361-
[ Pp.textf
362-
"no context in directory %s"
363-
(Path.Build.to_string_maybe_quoted dir)
364-
]
365-
in
366-
let+ dune_file = Script.eval_one ~context script in
367-
Some dune_file))
368-
;;
369-
370326
let load =
371327
let memo = Memo.lazy_ ~name:"dune_load" load in
372328
fun () -> Memo.Lazy.force memo

src/dune_rules/dune_load.mli

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ end
1414

1515
type t
1616

17-
val in_dir : Path.Build.t -> Dune_file.t option Memo.t
1817
val dune_files : t -> Dune_files.t
1918
val packages : t -> Package.t Package.Name.Map.t
2019
val projects : t -> Dune_project.t list

src/dune_rules/only_packages.ml

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,33 @@ let filter_out_stanzas_from_hidden_packages ~visible_pkgs =
100100
| _ -> None))
101101
;;
102102

103+
type filtered_stanzas =
104+
{ all : Dune_file.t list
105+
; map : Dune_file.t Path.Source.Map.t
106+
}
107+
103108
let filtered_stanzas =
104109
let db =
105110
Per_context.create_by_name ~name:"filtered_stanzas"
106111
@@ fun context ->
107112
let* only_packages = Memo.Lazy.force conf
108113
and+ dune_files = Dune_load.load () >>| Dune_load.dune_files in
109114
let+ stanzas = Dune_load.Dune_files.eval ~context dune_files in
110-
match only_packages with
111-
| None -> stanzas
112-
| Some visible_pkgs ->
113-
List.map stanzas ~f:(fun (dir_conf : Dune_file.t) ->
114-
{ dir_conf with
115-
stanzas = filter_out_stanzas_from_hidden_packages ~visible_pkgs dir_conf.stanzas
116-
})
115+
let all =
116+
match only_packages with
117+
| None -> stanzas
118+
| Some visible_pkgs ->
119+
List.map stanzas ~f:(fun (dune_file : Dune_file.t) ->
120+
{ dune_file with
121+
stanzas =
122+
filter_out_stanzas_from_hidden_packages ~visible_pkgs dune_file.stanzas
123+
})
124+
in
125+
let map =
126+
Path.Source.Map.of_list_map_exn all ~f:(fun (dune_file : Dune_file.t) ->
127+
dune_file.dir, dune_file)
128+
in
129+
{ all; map }
117130
in
118131
fun ctx -> Staged.unstage db ctx
119132
;;
@@ -127,17 +140,16 @@ let get () =
127140
let stanzas_in_dir dir =
128141
if Path.Build.is_root dir
129142
then Memo.return None
130-
else
131-
Dune_load.in_dir dir
132-
>>= function
143+
else (
144+
match Install.Context.of_path dir with
133145
| None -> Memo.return None
134-
| Some dune_file ->
135-
let+ stanzas =
136-
Memo.Lazy.force conf
137-
>>| function
138-
| None -> dune_file.stanzas
139-
| Some visible_pkgs ->
140-
filter_out_stanzas_from_hidden_packages ~visible_pkgs dune_file.stanzas
141-
in
142-
Some { dune_file with stanzas }
146+
| Some ctx ->
147+
let+ filtered_stanzas = filtered_stanzas ctx in
148+
let dir = Path.Build.drop_build_context_exn dir in
149+
Path.Source.Map.find filtered_stanzas.map dir)
150+
;;
151+
152+
let filtered_stanzas ctx =
153+
let+ filtered_stanzas = filtered_stanzas ctx in
154+
filtered_stanzas.all
143155
;;

0 commit comments

Comments
 (0)