Module Mavryk_base.Profiler

This profiling library declares a high-level interface meant to be used to instrument code in order to measure the time spent in the different parts in such a way to yield a (human-)processable report. This module declares a generic interface (driver) that will provide an API to the developer to instrument the code. When the profiling data is recorded, the abstracted profiler will feed it to its "plugged" backend (instance) which will process the different profiler's nodes in order to produce the reports. Reports may also be combined to interwine different components' traces.

The provided API is intentionally simplistic to simplify its usage. The basic usage is to call record <symbol> before the desired section to profile and stop () when we exit it. Nested calls are also supported and, given that the backend supports it, will be displayed as a callgraph. The API is also augmented with higher-level combinators in order to avoid mismatched stops and to support Lwt function calls.

type time = {
  1. wall : float;
    (*

    Wall-clock time: total time elapsed.

    *)
  2. cpu : float;
    (*

    CPU time: time elapsed in the CPU.

    *)
}
type span =
  1. | Span of time
val zero_time : span
val (-*) : time -> time -> time
val (+*) : time -> time -> time
type lod =
  1. | Terse
  2. | Detailed
  3. | Verbose

The level of detail of report sections. The driver can choose to use this information to skip or aggregate sections below a given level. The driver could also record everything, including the level of detail, and let a post processor skip or aggregate at display time.

type aggregated_node = {
  1. count : int;
  2. total : span;
  3. children : aggregated_node StringMap.t;
  4. node_lod : lod;
}

An aggregate node registers multiple calls to a section and sum their occurences and time. It also recursively aggregate its sub-aggregation nodes.

type seq_item = {
  1. start : time;
  2. duration : span;
  3. contents : report;
  4. item_lod : lod;
}

A sequence item registers one section with potential sub-reports and registers elapsed-time.

and report = {
  1. aggregated : aggregated_node StringMap.t;
  2. recorded : (string * seq_item) list;
}
val report_encoding : report Data_encoding.t
type (_, _) kind = ..
module type DRIVER = sig ... end
type 'a driver = (module DRIVER with type config = 'a)
type instance
val instance : 'a driver -> 'a -> instance
val time : instance -> time
val report : instance -> report option
val report_s : instance -> report Lwt.t
val close : instance -> unit
type profiler
val plug : profiler -> instance -> unit
val unplug : profiler -> instance -> unit
val close_and_unplug : profiler -> instance -> unit
val close_and_unplug_all : profiler -> unit
val plugged : profiler -> instance list
val record : profiler -> ?lod:lod -> string -> unit
val aggregate : profiler -> ?lod:lod -> string -> unit
val stop : profiler -> unit
val stamp : profiler -> ?lod:lod -> string -> unit
val mark : profiler -> ?lod:lod -> string list -> unit
val span : profiler -> ?lod:lod -> span -> string list -> unit
val inc : profiler -> report -> unit
val record_f : profiler -> ?lod:lod -> string -> (unit -> 'a) -> 'a
val record_s : profiler -> ?lod:lod -> string -> (unit -> 'a Lwt.t) -> 'a Lwt.t
val aggregate_f : profiler -> ?lod:lod -> string -> (unit -> 'a) -> 'a
val aggregate_s : profiler -> ?lod:lod -> string -> (unit -> 'a Lwt.t) -> 'a Lwt.t
val span_f : profiler -> ?lod:lod -> string list -> (unit -> 'a) -> 'a
val span_s : profiler -> ?lod:lod -> string list -> (unit -> 'a Lwt.t) -> 'a Lwt.t
val with_new_profiler : 'a driver -> 'a -> (profiler -> 'r) -> 'r * report list
val with_new_profiler_s : 'a driver -> 'a -> (profiler -> 'r Lwt.t) -> ('r * report list) Lwt.t
val unplugged : unit -> profiler
val main : profiler
module type GLOBAL_PROFILER = sig ... end
val wrap : profiler -> (module GLOBAL_PROFILER)