The objective of Stats_reporting is reporting numbers from a running process effeciently with minimum disruption to its execution time. The collected numbers can be analyzed offline after the process has exited.

Stats_reporting acts as a fine-grained performance analysis tool by letting us measure user specified stats. For instance one might want to report the length of a list, the number of elements of a hashtable, the code path taken, the latency between two points in code etc. and understand how large or small these values get, various quantiles, histograms etc. The tool for offline analysis is called stats.exe and lives in tool/stats.

Production binaries should not be built with Stats_reporting enabled.

val init : msg:string -> ?memory_limit:int -> ?file_name:string -> unit -> unit
init should be called early in program execution, probably in main. Once called, the process will write out a data file when the program exits or when the memory_limit is reached. If another process writes to the same data file, the file will be corrupt. The data file is named stats.data by default and the msg, typically a version string, is written out to it.
val adjust_internal_buffers_if_required : unit -> unit
adjust_internal_buffers_if_required is meant to be called outside any performance critical parts of your code. The point of this call is that it will do any upcoming housekeeping tasks so that they don't happen in performance critical bits of the code.

adjust_internal_buffers_if_required will (1) allocate additional memory if the module's internal buffers are close to being full and (2) write out data collected thus far if it is close to the specified memory_limit.

module Field : sig .. end
Values are reported using Field.ts.
type 'a t = private int
val create : desc:string -> type_desc:string -> name:string -> 'a t
create creates an abstract field whose value will be reported at different points in time. Fields are typically global to a module.
val add_datum : int t -> int -> unit
add_datum and add_datum_float report data changes.
val add_datum_float : float t -> float -> unit
val bin_t : 'a Core.Std.Bin_prot.Type_class.t -> 'a t Core.Std.Bin_prot.Type_class.t
val bin_read_t : 'a Core.Std.Bin_prot.Read.reader -> 'a t Core.Std.Bin_prot.Read.reader
val __bin_read_t__ : 'a Core.Std.Bin_prot.Read.reader ->
(int -> 'a t) Core.Std.Bin_prot.Read.reader
val bin_reader_t : 'a Core.Std.Bin_prot.Type_class.reader ->
'a t Core.Std.Bin_prot.Type_class.reader
val bin_size_t : 'a Core.Std.Bin_prot.Size.sizer -> 'a t Core.Std.Bin_prot.Size.sizer
val bin_write_t : 'a Core.Std.Bin_prot.Write.writer -> 'a t Core.Std.Bin_prot.Write.writer
val bin_writer_t : 'a Core.Std.Bin_prot.Type_class.writer ->
'a t Core.Std.Bin_prot.Type_class.writer
val t_of_sexp : (Sexplib.Sexp.t -> 'a) -> Sexplib.Sexp.t -> 'a t
val sexp_of_t : ('a -> Sexplib.Sexp.t) -> 'a t -> Sexplib.Sexp.t
module Delta : sig .. end
Delta makes it easy to record deltas of values. For instance, if one wants to record the number of minor words allocated in some part of code one would do first create a Delta.t and then write the following to report the value of minor_words2 - minor_words1:
        set_datum t minor_words1;

        ... code to test ...;

        add_delta t minor_words2;
type 'a t
val create : 'a Field.t -> 'a t
val set : int t -> int -> unit
set t v1 sets the current value to v. v is not reported -- add_delta or add_delta_and_set must be subsequently called. add_delta t v2 causes v2-v1 to be reported, for the latest set t v1. add_delta_and_set t v2 is add_delta t v2 followed by set t v2.
val add_delta : int t -> int -> unit
val add_delta_and_set : int t -> int -> unit
val set_float : float t -> float -> unit
Similar to the int functions above.
val add_delta_float : float t -> float -> unit
val add_delta_and_set_float : float t -> float -> unit
module Field_id : sig .. end
type t = private int
include Core.Std.Identifiable with type t := t
include Core.Std.Intable with type t := t
module Reader : sig .. end
Reader is meant to be used by code that reads stats.data files.
type type_desc = string
type name = string
type t = 
|New_field of Field_id.t * string * type_desc * name
|Int_datum of Field_id.t * int * Core.Std.Time_stamp_counter.t
|Float_datum of Field_id.t * float * Core.Std.Time_stamp_counter.t
val read_msg_and_snapshot : file:string -> string * Core.Std.Time_stamp_counter.Calibrator.t
val fold : file:string -> init:'a -> f:('a -> t -> 'a) -> 'a
val bin_type_desc : type_desc Core.Std.Bin_prot.Type_class.t
val bin_read_type_desc : type_desc Core.Std.Bin_prot.Read.reader
val __bin_read_type_desc__ : (int -> type_desc) Core.Std.Bin_prot.Read.reader
val bin_reader_type_desc : type_desc Core.Std.Bin_prot.Type_class.reader
val bin_size_type_desc : type_desc Core.Std.Bin_prot.Size.sizer
val bin_write_type_desc : type_desc Core.Std.Bin_prot.Write.writer
val bin_writer_type_desc : type_desc Core.Std.Bin_prot.Type_class.writer
val type_desc_of_sexp : Sexplib.Sexp.t -> type_desc
val sexp_of_type_desc : type_desc -> Sexplib.Sexp.t
val bin_name : name Core.Std.Bin_prot.Type_class.t
val bin_read_name : name Core.Std.Bin_prot.Read.reader
val __bin_read_name__ : (int -> name) Core.Std.Bin_prot.Read.reader
val bin_reader_name : name Core.Std.Bin_prot.Type_class.reader
val bin_size_name : name Core.Std.Bin_prot.Size.sizer
val bin_write_name : name Core.Std.Bin_prot.Write.writer
val bin_writer_name : name Core.Std.Bin_prot.Type_class.writer
val name_of_sexp : Sexplib.Sexp.t -> name
val sexp_of_name : name -> Sexplib.Sexp.t
val bin_t : t Core.Std.Bin_prot.Type_class.t
val bin_read_t : t Core.Std.Bin_prot.Read.reader
val __bin_read_t__ : (int -> t) Core.Std.Bin_prot.Read.reader
val bin_reader_t : t Core.Std.Bin_prot.Type_class.reader
val bin_size_t : t Core.Std.Bin_prot.Size.sizer
val bin_write_t : t Core.Std.Bin_prot.Write.writer
val bin_writer_t : t Core.Std.Bin_prot.Type_class.writer
val t_of_sexp : Sexplib.Sexp.t -> t
val sexp_of_t : t -> Sexplib.Sexp.t