<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta name="robots" content="index,nofollow"> <title>MLtonProfile - MLton Standard ML Compiler (SML Compiler)</title> <link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css"> <link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css"> <link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css"> <link rel="Start" href="Home"> </head> <body lang="en" dir="ltr"> <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-833377-1"; urchinTracker(); </script> <table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%> <tr> <td style = " border: 0px; color: darkblue; font-size: 150%; text-align: left;"> <a class = mltona href="Home">MLton MLTONWIKIVERSION</a> <td style = " border: 0px; font-size: 150%; text-align: center; width: 50%;"> MLtonProfile <td style = " border: 0px; text-align: right;"> <table cellspacing = 0 style = "border: 0px"> <tr style = "vertical-align: middle;"> </table> <tr style = "background-color: white;"> <td colspan = 3 style = " border: 0px; font-size:70%; text-align: right;"> <a href = "Home">Home</a> <a href = "TitleIndex">Index</a> </table> <div id="content" lang="en" dir="ltr"> <pre class=code> <B><FONT COLOR="#0000FF">signature</FONT></B> MLTON_PROFILE = <B><FONT COLOR="#0000FF">sig</FONT></B> <B><FONT COLOR="#0000FF">structure</FONT></B> Data: <B><FONT COLOR="#0000FF">sig</FONT></B> <B><FONT COLOR="#A020F0">type</FONT></B><B><FONT COLOR="#228B22"> t </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> equals: t * t -> bool <B><FONT COLOR="#A020F0">val</FONT></B> free: t -> unit <B><FONT COLOR="#A020F0">val</FONT></B> malloc: unit -> t <B><FONT COLOR="#A020F0">val</FONT></B> write: t * string -> unit <B><FONT COLOR="#0000FF">end</FONT></B> <B><FONT COLOR="#A020F0">val</FONT></B> isOn: bool <B><FONT COLOR="#A020F0">val</FONT></B> withData: Data.t * (unit -> 'a) -> 'a <B><FONT COLOR="#0000FF">end</FONT></B> </PRE> <p> </p> <p> <tt>MLton.Profile</tt> provides <a href="Profiling">Profiling</a> control from within the program, allowing you to profile individual portions of your program. With <tt>MLton.Profile</tt>, you can create many units of profiling data (essentially, mappings from functions to counts) during a run of a program, switch between them while the program is running, and output multiple <tt>mlmon.out</tt> files. </p> <ul> <li> <p> <tt>isOn</tt> <br> a compile-time constant that is false only when compiling <tt>-profile no</tt>. </p> </li> <li class="gap"> <p> <tt>type Data.t</tt> <br> the type of a unit of profiling data. In order to most efficiently execute non-profiled programs, when compiling <tt>-profile no</tt> (the default), <tt>Data.t</tt> is equivalent to <tt>unit ref</tt>. </p> </li> <li class="gap"> <p> <tt>Data.equals (x, y)</tt> <br> returns true if the <tt>x</tt> and <tt>y</tt> are the same unit of profiling data. </p> </li> <li class="gap"> <p> <tt>Data.free x</tt> <br> frees the memory associated with the unit of profiling data <tt>x</tt>. It is an error to free the current unit of profiling data or to free a previously freed unit of profiling data. When compiling <tt>-profile no</tt>, <tt>Data.free x</tt> is a no-op. </p> </li> <li class="gap"> <p> <tt>Data.malloc ()</tt> <br> returns a new unit of profiling data. Each unit of profiling data is allocated from the process address space (but is <em>not</em> in the MLton heap) and consumes memory proportional to the number of source functions. When compiling <tt>-profile no</tt>, <tt>Data.malloc ()</tt> is equivalent to allocating a new <tt>unit ref</tt>. </p> </li> <li class="gap"> <p> <tt>write (x, f)</tt> <br> writes the accumulated ticks in the unit of profiling data <tt>x</tt> to file <tt>f</tt>. It is an error to write a previously freed unit of profiling data. When compiling <tt>-profile no</tt>, <tt>write (x, f)</tt> is a no-op. A profiled program will always write the current unit of profiling data at program exit to a file named <tt>mlmon.out</tt>. </p> </li> <li class="gap"> <p> <tt>withData (d, f)</tt> <br> runs <tt>f</tt> with <tt>d</tt> as the unit of profiling data, and returns the result of <tt>f</tt> after restoring the current unit of profiling data. When compiling <tt>-profile no</tt>, <tt>withData (d, f)</tt> is equivalent to <tt>f ()</tt>. </p> </li> </ul> <h2 id="head-0f01ed56a1e32a05e5ef96e4d779f34784af9a96">Example</h2> <p> Here is an example, taken from the <tt>examples/profiling</tt> directory, showing how to profile the executions of the <tt>fib</tt> and <tt>tak</tt> functions separately. Suppose that <tt>fib-tak.sml</tt> contains the following. </p> <pre class=code> <B><FONT COLOR="#0000FF">structure</FONT></B> Profile = MLton.Profile <B><FONT COLOR="#A020F0">val</FONT></B> fibData = Profile.Data.malloc () <B><FONT COLOR="#A020F0">val</FONT></B> takData = Profile.Data.malloc () <B><FONT COLOR="#A020F0">fun</FONT></B> wrap (f, d) x = Profile.withData (d, <B><FONT COLOR="#A020F0">fn</FONT></B> () => f x) <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#A020F0">rec</FONT></B> fib = <B><FONT COLOR="#A020F0">fn</FONT></B> <B><FONT COLOR="#5F9EA0">0</FONT></B> => <B><FONT COLOR="#5F9EA0">0</FONT></B> | <B><FONT COLOR="#5F9EA0">1</FONT></B> => <B><FONT COLOR="#5F9EA0">1</FONT></B> | n => fib (n - <B><FONT COLOR="#5F9EA0">1</FONT></B>) + fib (n - <B><FONT COLOR="#5F9EA0">2</FONT></B>) <B><FONT COLOR="#A020F0">val</FONT></B> fib = wrap (fib, fibData) <B><FONT COLOR="#A020F0">fun</FONT></B> tak (x,y,z) = <B><FONT COLOR="#A020F0">if</FONT></B> not (y < x) <B><FONT COLOR="#A020F0">then</FONT></B> z <B><FONT COLOR="#A020F0">else</FONT></B> tak (tak (x - <B><FONT COLOR="#5F9EA0">1</FONT></B>, y, z), tak (y - <B><FONT COLOR="#5F9EA0">1</FONT></B>, z, x), tak (z - <B><FONT COLOR="#5F9EA0">1</FONT></B>, x, y)) <B><FONT COLOR="#A020F0">val</FONT></B> tak = wrap (tak, takData) <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#A020F0">rec</FONT></B> f = <B><FONT COLOR="#A020F0">fn</FONT></B> <B><FONT COLOR="#5F9EA0">0</FONT></B> => () | n => (fib <B><FONT COLOR="#5F9EA0">38</FONT></B>; f (n-<B><FONT COLOR="#5F9EA0">1</FONT></B>)) <B><FONT COLOR="#A020F0">val</FONT></B> _ = f <B><FONT COLOR="#5F9EA0">2</FONT></B> <B><FONT COLOR="#A020F0">val</FONT></B> <B><FONT COLOR="#A020F0">rec</FONT></B> g = <B><FONT COLOR="#A020F0">fn</FONT></B> <B><FONT COLOR="#5F9EA0">0</FONT></B> => () | n => (tak (<B><FONT COLOR="#5F9EA0">18</FONT></B>,<B><FONT COLOR="#5F9EA0">12</FONT></B>,<B><FONT COLOR="#5F9EA0">6</FONT></B>); g (n-<B><FONT COLOR="#5F9EA0">1</FONT></B>)) <B><FONT COLOR="#A020F0">val</FONT></B> _ = g <B><FONT COLOR="#5F9EA0">500</FONT></B> <B><FONT COLOR="#A020F0">fun</FONT></B> done (data, file) = (Profile.Data.write (data, file) ; Profile.Data.free data) <B><FONT COLOR="#A020F0">val</FONT></B> _ = done (fibData, <B><FONT COLOR="#BC8F8F">"mlmon.fib.out"</FONT></B>) <B><FONT COLOR="#A020F0">val</FONT></B> _ = done (takData, <B><FONT COLOR="#BC8F8F">"mlmon.tak.out"</FONT></B>) </PRE> <p> </p> <p> Compile and run the program. </p> <pre>% mlton -profile time fib-tak.sml % ./fib-tak </pre><p> Separately display the profiling data for <tt>fib</tt> </p> <pre>% mlprof fib-tak mlmon.fib.out 5.77 seconds of CPU time (0.00 seconds GC) function cur --------- ----- fib 96.9% <unknown> 3.1% </pre><p> and for <tt>tak</tt> </p> <pre>% mlprof fib-tak mlmon.tak.out 0.68 seconds of CPU time (0.00 seconds GC) function cur -------- ------ tak 100.0% </pre><p> Combine the data for <tt>fib</tt> and <tt>tak</tt> by calling <tt>mlprof</tt> with multiple <tt>mlmon.out</tt> files. </p> <pre>% mlprof fib-tak mlmon.fib.out mlmon.tak.out mlmon.out 6.45 seconds of CPU time (0.00 seconds GC) function cur --------- ----- fib 86.7% tak 10.5% <unknown> 2.8% </pre></div> <p> <hr> Last edited on 2007-08-23 03:44:58 by <span title="c-71-57-91-146.hsd1.il.comcast.net"><a href="MatthewFluet">MatthewFluet</a></span>. </body></html>