From 7b4dfad9ec15c8f12994c4e602b7ebd37dc7c70c Mon Sep 17 00:00:00 2001 From: Stephen Sherratt Date: Wed, 1 Jan 2025 12:18:26 +1100 Subject: [PATCH] pkg: add argument to pkg lock to print perf stats Signed-off-by: Stephen Sherratt --- bin/lock_dev_tool.ml | 1 + bin/pkg/lock.ml | 47 +++++++++++++++++++++++++----------- bin/pkg/lock.mli | 1 + src/dune_pkg/opam_solver.ml | 27 ++++++++++++++++++++- src/dune_pkg/opam_solver.mli | 1 + 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/bin/lock_dev_tool.ml b/bin/lock_dev_tool.ml index ad23709bae2..9da37c7a409 100644 --- a/bin/lock_dev_tool.ml +++ b/bin/lock_dev_tool.ml @@ -81,6 +81,7 @@ let solve ~dev_tool ~local_packages = ~solver_env_from_current_system ~version_preference:None ~lock_dirs:[ lock_dir ] + ~print_perf_stats:false ;; let compiler_package_name = Package_name.of_string "ocaml" diff --git a/bin/pkg/lock.ml b/bin/pkg/lock.ml index 541612eb2a3..152a5d43e1b 100644 --- a/bin/pkg/lock.ml +++ b/bin/pkg/lock.ml @@ -70,6 +70,7 @@ let solve_lock_dir workspace ~local_packages ~project_pins + ~print_perf_stats version_preference solver_env_from_current_system lock_dir_path @@ -94,6 +95,7 @@ let solve_lock_dir ~unset_solver_vars_from_context: (unset_solver_vars_of_workspace workspace ~lock_dir_path) in + let time_start = Unix.gettimeofday () in let* repos = let repo_map = repositories_of_workspace workspace in let repo_names = @@ -105,6 +107,7 @@ let solve_lock_dir get_repos repo_map ~repositories:(repositories_of_lock_dir workspace ~lock_dir_path) in let* pins = resolve_project_pins project_pins in + let time_solve_start = Unix.gettimeofday () in progress_state := Some Progress_indicator.Per_lockdir.State.Solving; Dune_pkg.Opam_solver.solve_lock_dir solver_env @@ -119,19 +122,30 @@ let solve_lock_dir ~constraints:(constraints_of_workspace workspace ~lock_dir_path) >>= function | Error (`Diagnostic_message message) -> Fiber.return (Error (lock_dir_path, message)) - | Ok { lock_dir; files; pinned_packages } -> + | Ok { lock_dir; files; pinned_packages; num_expanded_packages } -> + let time_end = Unix.gettimeofday () in + let maybe_perf_stats = + if print_perf_stats + then + [ Pp.nop + ; Pp.textf "Expanded packages: %d" num_expanded_packages + ; Pp.textf "Updated repos in: %.2fs" (time_solve_start -. time_start) + ; Pp.textf "Solved dependencies in: %.2fs" (time_end -. time_solve_start) + ] + else [] + in let summary_message = User_message.make - [ Pp.tag - User_message.Style.Success - (Pp.textf - "Solution for %s:" - (Path.Source.to_string_maybe_quoted lock_dir_path)) - ; (match Package_name.Map.values lock_dir.packages with - | [] -> - Pp.tag User_message.Style.Warning @@ Pp.text "(no dependencies to lock)" - | packages -> pp_packages packages) - ] + (Pp.tag + User_message.Style.Success + (Pp.textf + "Solution for %s:" + (Path.Source.to_string_maybe_quoted lock_dir_path)) + :: (match Package_name.Map.values lock_dir.packages with + | [] -> + Pp.tag User_message.Style.Warning @@ Pp.text "(no dependencies to lock)" + | packages -> pp_packages packages) + :: maybe_perf_stats) in progress_state := None; let+ lock_dir = Lock_dir.compute_missing_checksums ~pinned_packages lock_dir in @@ -145,6 +159,7 @@ let solve ~solver_env_from_current_system ~version_preference ~lock_dirs + ~print_perf_stats = let open Fiber.O in (* a list of thunks that will perform all the file IO side @@ -166,6 +181,7 @@ let solve workspace ~local_packages ~project_pins + ~print_perf_stats version_preference solver_env_from_current_system lockdir_path @@ -198,7 +214,7 @@ let project_pins = Pin_stanza.DB.combine_exn acc (Dune_project.pins project)) ;; -let lock ~version_preference ~lock_dirs_arg = +let lock ~version_preference ~lock_dirs_arg ~print_perf_stats = let open Fiber.O in let* solver_env_from_current_system = Dune_pkg.Sys_poll.make ~path:(Env_path.path Stdune.Env.initial) @@ -223,15 +239,18 @@ let lock ~version_preference ~lock_dirs_arg = ~solver_env_from_current_system ~version_preference ~lock_dirs + ~print_perf_stats ;; let term = let+ builder = Common.Builder.term and+ version_preference = Version_preference.term - and+ lock_dirs_arg = Pkg_common.Lock_dirs_arg.term in + and+ lock_dirs_arg = Pkg_common.Lock_dirs_arg.term + and+ print_perf_stats = Arg.(value & flag & info [ "print-perf-stats" ]) in let builder = Common.Builder.forbid_builds builder in let common, config = Common.init builder in - Scheduler.go ~common ~config (fun () -> lock ~version_preference ~lock_dirs_arg) + Scheduler.go ~common ~config (fun () -> + lock ~version_preference ~lock_dirs_arg ~print_perf_stats) ;; let info = diff --git a/bin/pkg/lock.mli b/bin/pkg/lock.mli index 132cdb66553..d9f99d43dc2 100644 --- a/bin/pkg/lock.mli +++ b/bin/pkg/lock.mli @@ -7,6 +7,7 @@ val solve -> solver_env_from_current_system:Dune_pkg.Solver_env.t option -> version_preference:Dune_pkg.Version_preference.t option -> lock_dirs:Path.Source.t list + -> print_perf_stats:bool -> unit Fiber.t (** Command to create lock directory *) diff --git a/src/dune_pkg/opam_solver.ml b/src/dune_pkg/opam_solver.ml index cd6066947a2..d1ed674c604 100644 --- a/src/dune_pkg/opam_solver.ml +++ b/src/dune_pkg/opam_solver.ml @@ -78,6 +78,9 @@ module Context = struct packages for which we've printed a warning. *) available_cache : (OpamPackage.t, bool) Table.t ; constraints : OpamTypes.filtered_formula Package_name.Map.t + ; (* Number of versions of each package whose opam files were read from + disk while solving. Used to report performance statistics. *) + expanded_packages : (Package_name.t, int) Table.t } let create @@ -105,6 +108,15 @@ module Context = struct end) 1 in + let expanded_packages = + Table.create + (module struct + include Package_name + + let to_dyn = Package_name.to_dyn + end) + 1 + in { repos ; version_preference ; local_packages @@ -115,6 +127,7 @@ module Context = struct ; candidates_cache ; available_cache ; constraints + ; expanded_packages } ;; @@ -180,6 +193,10 @@ module Context = struct let repo_candidate t name = let+ resolved = Opam_repo.load_all_versions t.repos name in + Table.add_exn + t.expanded_packages + (Package_name.of_opam_package_name name) + (OpamPackage.Version.Map.cardinal resolved); let available = OpamPackage.Version.Map.values resolved |> List.map ~f:(fun p -> p, Priority.make (Resolved_package.opam_file p)) @@ -252,6 +269,8 @@ module Context = struct ~with_test:package_is_local filtered_formula ;; + + let count_expanded_packages t = Table.fold t.expanded_packages ~init:0 ~f:( + ) end module Solver = struct @@ -1738,6 +1757,7 @@ module Solver_result = struct { lock_dir : Lock_dir.t ; files : File_entry.t Package_name.Map.Multi.t ; pinned_packages : Package_name.Set.t + ; num_expanded_packages : int } end @@ -1965,5 +1985,10 @@ let solve_lock_dir >>| List.filter ~f:(fun (_, entries) -> List.is_non_empty entries) >>| Package_name.Map.of_list_exn in - Ok { Solver_result.lock_dir; files; pinned_packages = pinned_package_names } + Ok + { Solver_result.lock_dir + ; files + ; pinned_packages = pinned_package_names + ; num_expanded_packages = Context_for_dune.count_expanded_packages context + } ;; diff --git a/src/dune_pkg/opam_solver.mli b/src/dune_pkg/opam_solver.mli index 781a78b84dd..21a0ac2954d 100644 --- a/src/dune_pkg/opam_solver.mli +++ b/src/dune_pkg/opam_solver.mli @@ -5,6 +5,7 @@ module Solver_result : sig { lock_dir : Lock_dir.t ; files : File_entry.t Package_name.Map.Multi.t ; pinned_packages : Package_name.Set.t + ; num_expanded_packages : int } end