Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / MLtonProfile.adoc
1 MLtonProfile
2 ============
3
4 [source,sml]
5 ----
6 signature MLTON_PROFILE =
7 sig
8 structure Data:
9 sig
10 type t
11
12 val equals: t * t -> bool
13 val free: t -> unit
14 val malloc: unit -> t
15 val write: t * string -> unit
16 end
17
18 val isOn: bool
19 val withData: Data.t * (unit -> 'a) -> 'a
20 end
21 ----
22
23 `MLton.Profile` provides <:Profiling:> control from within the
24 program, allowing you to profile individual portions of your
25 program. With `MLton.Profile`, you can create many units of profiling
26 data (essentially, mappings from functions to counts) during a run of
27 a program, switch between them while the program is running, and
28 output multiple `mlmon.out` files.
29
30 * `isOn`
31 +
32 a compile-time constant that is false only when compiling `-profile no`.
33
34 * `type Data.t`
35 +
36 the type of a unit of profiling data. In order to most efficiently
37 execute non-profiled programs, when compiling `-profile no` (the
38 default), `Data.t` is equivalent to `unit ref`.
39
40 * `Data.equals (x, y)`
41 +
42 returns true if the `x` and `y` are the same unit of profiling data.
43
44 * `Data.free x`
45 +
46 frees the memory associated with the unit of profiling data `x`. It
47 is an error to free the current unit of profiling data or to free a
48 previously freed unit of profiling data. When compiling
49 `-profile no`, `Data.free x` is a no-op.
50
51 * `Data.malloc ()`
52 +
53 returns a new unit of profiling data. Each unit of profiling data is
54 allocated from the process address space (but is _not_ in the MLton
55 heap) and consumes memory proportional to the number of source
56 functions. When compiling `-profile no`, `Data.malloc ()` is
57 equivalent to allocating a new `unit ref`.
58
59 * `write (x, f)`
60 +
61 writes the accumulated ticks in the unit of profiling data `x` to file
62 `f`. It is an error to write a previously freed unit of profiling
63 data. When compiling `-profile no`, `write (x, f)` is a no-op. A
64 profiled program will always write the current unit of profiling data
65 at program exit to a file named `mlmon.out`.
66
67 * `withData (d, f)`
68 +
69 runs `f` with `d` as the unit of profiling data, and returns the
70 result of `f` after restoring the current unit of profiling data.
71 When compiling `-profile no`, `withData (d, f)` is equivalent to
72 `f ()`.
73
74
75 == Example ==
76
77 Here is an example, taken from the `examples/profiling` directory,
78 showing how to profile the executions of the `fib` and `tak` functions
79 separately. Suppose that `fib-tak.sml` contains the following.
80 [source,sml]
81 ----
82 structure Profile = MLton.Profile
83
84 val fibData = Profile.Data.malloc ()
85 val takData = Profile.Data.malloc ()
86
87 fun wrap (f, d) x =
88 Profile.withData (d, fn () => f x)
89
90 val rec fib =
91 fn 0 => 0
92 | 1 => 1
93 | n => fib (n - 1) + fib (n - 2)
94 val fib = wrap (fib, fibData)
95
96 fun tak (x,y,z) =
97 if not (y < x)
98 then z
99 else tak (tak (x - 1, y, z),
100 tak (y - 1, z, x),
101 tak (z - 1, x, y))
102 val tak = wrap (tak, takData)
103
104 val rec f =
105 fn 0 => ()
106 | n => (fib 38; f (n-1))
107 val _ = f 2
108
109 val rec g =
110 fn 0 => ()
111 | n => (tak (18,12,6); g (n-1))
112 val _ = g 500
113
114 fun done (data, file) =
115 (Profile.Data.write (data, file)
116 ; Profile.Data.free data)
117
118 val _ = done (fibData, "mlmon.fib.out")
119 val _ = done (takData, "mlmon.tak.out")
120 ----
121
122 Compile and run the program.
123 ----
124 % mlton -profile time fib-tak.sml
125 % ./fib-tak
126 ----
127
128 Separately display the profiling data for `fib`
129 ----
130 % mlprof fib-tak mlmon.fib.out
131 5.77 seconds of CPU time (0.00 seconds GC)
132 function cur
133 --------- -----
134 fib 96.9%
135 <unknown> 3.1%
136 ----
137 and for `tak`
138 ----
139 % mlprof fib-tak mlmon.tak.out
140 0.68 seconds of CPU time (0.00 seconds GC)
141 function cur
142 -------- ------
143 tak 100.0%
144 ----
145
146 Combine the data for `fib` and `tak` by calling `mlprof`
147 with multiple `mlmon.out` files.
148 ----
149 % mlprof fib-tak mlmon.fib.out mlmon.tak.out mlmon.out
150 6.45 seconds of CPU time (0.00 seconds GC)
151 function cur
152 --------- -----
153 fib 86.7%
154 tak 10.5%
155 <unknown> 2.8%
156 ----