File: profiling.html

package info (click to toggle)
yap 5.1.1-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 16,124 kB
  • ctags: 14,650
  • sloc: ansic: 122,796; perl: 22,545; sh: 3,768; java: 1,277; makefile: 1,191; xml: 739; tcl: 624; lisp: 142; awk: 9
file content (150 lines) | stat: -rw-r--r-- 7,466 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
	<meta http-equiv="content-type" content="application/xml+xhtml; charset=utf-8" />
    <title>Logtalk tutorial: profiling programs</title>
	<link rel="stylesheet" href="../screen.css" type="text/css" media="screen"/>
	<link rel="stylesheet" href="../print.css" type="text/css" media="print"/>
</head>

<body>

<div class="top-left">Logtalk tutorial</div> 
<div class="top-right">Profiling programs</div>
<div class="bottom-left"><span class="page"/></div> 
<div class="bottom-right"><span class="page"/></div>
<div class="navtop"><a href="../index.html">contents</a> &gt; <a href="index.html">tutorial</a></div>

<h1>Profiling programs</h1>

<p>
In this example, we will illustrate the use of:
</p>
<ul>
	<li>events</li>
	<li>monitors</li>
</ul>
<p>
by defining a simple profiler that prints the starting and ending time for processing a message sent to an object.
</p>

<h2>Messages as events<a id="events"></a></h2>

<p>
In a pure object-oriented system, all computations start by sending messages to objects. We can thus define an <em>event</em> as the sending of a message to an object. An event can then be specified by the tuple <code>(Object, Message, Sender)</code>. This definition can be refined by interpreting the sending of a message and the return of the control to the object that has sent the message as two distinct events. We call these events respectively <code>before</code> and <code>after</code>. Therefore, we end up by representing an event by the tuple <code>(Event, Object, Message, Sender)</code>. For instance, if we send the message:
</p>
<pre>| ?- foo::bar(X).

X = 1
yes</pre>
<p>
the two corresponding events will be:
</p>
<pre>(before, foo, bar(X), user)
(after, foo, bar(1), user)</pre>
<p>
Note that the second event is only generated if the message succeeds. If the message as a goal have multiple solutions, then one <code>after</code> event will be generated for each solution.
</p>
<p>
Events are automatically generated by the message sending mechanisms for each public message sent using the <a title="Consult reference manual" href="../refman/control/to_object2.html"><code>::/2</code></a> operator.
</p>

<h2>Profilers as monitors<a id="monitors"></a></h2>

<p>
A monitor is an object that reacts whenever a spied event occurs. The monitor actions are defined by two event handlers: <a title="Consult reference manual" href="../refman/methods/before3.html"><code>before/3</code></a> for <code>before</code> events and <a title="Consult reference manual" href="../refman/methods/after3.html"><code>after/3</code></a> for <code>after</code> events. These predicates are automatically called by the message sending mechanisms when an event registered for the monitor occurs.
</p>
<p>
In our example, we need a way to get the current time before and after we process a message. We will assume that we have a <code>time</code> object implementing a <code>cpu_time/1</code> predicate that returns the current CPU time for the Prolog session:
</p>
<pre>:- object(time).

    :- public(cpu_time/1).
    :- mode(cpu_time(-number), one).

    ...

:- end_object.</pre>
<p>
Our profiler will be named <code>stop_watch</code>. It must define event handlers for the <code>before</code> and <code>after</code> events that will print the event description (object, message, and sender) and the current time:
</p>
<pre>:- object(stop_watch).

    :- uses(time).

    before(Object, Message, Sender) :-
        write(Object), write(' &lt;-- '), writeq(Message),
        write(' from '), write(Sender), nl, write('STARTING at '),
        time::cpu_time(Seconds), write(Seconds), write(' seconds'), nl.

    after(Object, Message, Sender) :-
        write(Object), write(' &lt;-- '), writeq(Message),
        write(' from '), write(Sender), nl, write('ENDING at '),
        time::cpu_time(Seconds), write(Seconds), write(' seconds'), nl.

:- end_object.</pre>
<p>
After compiling and loading the <code>stop_watch</code> object (and the objects that we want to profile), we can use the <a title="Consult reference manual" href="../refman/builtins/define_events5.html"><code>define_events/5</code></a> built-in predicate to set up our profiler. For example, to profile all messages that are sent to the object <code>foo</code>, we need to call the goal:
</p>
<pre>| ?- define_events(_, foo, _, _, stop_watch).

yes</pre>
<p>
This call will register <code>stop_watch</code> as a monitor to all messages sent to object <code>foo</code>, for both <code>before</code> and <code>after</code> events. Note that we say &quot;as a monitor&quot;, not &quot;the monitor&quot;: we can have any number of monitors over the same events.
</p>
<p>
From now on, every time we sent a message to <code>foo</code>, the <code>stop_watch</code> monitor will print the starting and ending times for the message execution. For instance:
</p>
<pre>| ?- foo::bar(X).

foo &lt;-- bar(X) from user
STARTING at 12.87415 seconds
foo &lt;-- bar(1) from user
ENDING at 12.87419 seconds

X = 1
yes</pre>
<p>
To stop profiling the messages sent to <code>foo</code> we use the <a title="Consult reference manual" href="../refman/builtins/abolish_events5.html"><code>abolish_events/5</code></a>
built-in predicate:
</p>
<pre>| ?- abolish_events(_, foo, _, _, stop_watch).

yes</pre>
<p>
This call will abolish all events defined over the object <code>foo</code> assigned to the <code>stop_watch</code> monitor.
</p>

<h2>Summary<a id="summary"></a></h2>

<ul>
    <li>An event is defined as the sending of a (public) message to an object.</li>
</ul>
<ul>
    <li>There are two kinds of events: <code>before</code> events, generated before a message is processed, and <code>after</code> events, generated after the message processing completed successfully.</li>
</ul>
<ul>
    <li>Any object can be declared as a monitor to any event.</li>
</ul>
<ul>
    <li>A monitor defines event handlers, the predicates <a title="Consult reference manual" href="../refman/methods/before3.html"><code>before/3</code></a> and <a title="Consult reference manual" href="../refman/methods/after3.html"><code>after/3</code></a>, that are automatically called by the runtime engine when a spied event occurs.</li>
</ul>
<ul>
    <li>Three built-in predicates, <a title="Consult reference manual" href="../refman/builtins/define_events5.html"><code>define_events/5</code></a>, <a title="Consult reference manual" href="../refman/builtins/current_event5.html"><code>current_event/5</code></a>, and <a title="Consult reference manual" href="../refman/builtins/abolish_events5.html"><code>abolish_events/5</code></a>, enables us define, query, and abolish both events and monitors.</li>
</ul>

<div class="footer">
	<div class="navbottom"><a href="reflection.html">previous</a> | <a href="../glossary.html">glossary</a> | <a href="index.html">next</a></div>
	<div class="copyright">Copyright &copy; <a href="mailto:pmoura@logtalk.org">Paulo Moura</a> &mdash; <a href="http://www.logtalk.org">Logtalk.org</a></div>
	<div class="footnote">
		<span class="validators"><a href="http://validator.w3.org/check/referer">XHTML</a> + <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></span>
		<span class="date">Last updated on: November 16, 2005</span>
	</div>
</div>

</body>
</html>