<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The Tale of Python</title>
	<atom:link href="http://pytong.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://pytong.wordpress.com</link>
	<description>"Make everything as simple as possible, but not simpler."</description>
	<lastBuildDate>Sun, 02 May 2010 09:03:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='pytong.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Tale of Python</title>
		<link>http://pytong.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://pytong.wordpress.com/osd.xml" title="The Tale of Python" />
	<atom:link rel='hub' href='http://pytong.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Timing parts of the application code in Python</title>
		<link>http://pytong.wordpress.com/2009/03/16/timing-parts-of-the-application-code-in-python/</link>
		<comments>http://pytong.wordpress.com/2009/03/16/timing-parts-of-the-application-code-in-python/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 18:30:55 +0000</pubDate>
		<dc:creator>pytong</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[stopwatch]]></category>
		<category><![CDATA[timing]]></category>

		<guid isPermaLink="false">http://pytong.wordpress.com/?p=3</guid>
		<description><![CDATA[Measuring application performance is a very important matter in the software development. Almost every framework comes with some tools to accomplish this task (such as Spring&#8217;s Stopwatch). Lately I was looking for such a class for Python and could not find any (for Google&#8217;a Appengine framework). There is a great timeit module, but it is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pytong.wordpress.com&amp;blog=6978677&amp;post=3&amp;subd=pytong&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Measuring application performance is a very important matter in the software development. Almost every framework comes with some tools to accomplish this task (such as Spring&#8217;s Stopwatch). Lately I was looking for such a class for Python and could not find any (for Google&#8217;a Appengine framework). There is a great <em><strong>timeit</strong></em> module, but it is useful to test only small portions of code.</p>
<p>I searched how the Java guys do that to eventually port their solution. On <a title="gustlik's blog" href="http://gustlik.wordpress.com" target="_blank">gustlik&#8217;s blog</a>, there was <a title="a very interesting implementation of the Stopwatch class" href="http://gustlik.wordpress.com/2008/06/20/hierarchical-stopwatch-measuring-code-performance/" target="_blank">a very interesting implementation of the Stopwatch class</a> which prints logs in a way that you can see a hierarchical structure of time consumption of individual pieces of code. Something like:</p>
<p><pre class="brush: xml;">
post : 32 ms
  __init__ : 29 ms
  save_user : 3 ms
</pre></p>
<p>This was exactly what I wanted in my application. The Java code was self-explanable so it was not very difficult to move it to the Python&#8217;s world.</p>
<p>Below you can find my implementation and some examples of usage.</p>
<p><pre class="brush: python;">
import logging
import threading
import time
from StringIO import StringIO

class Event(object):
  '''
  Event class for stopwatch.
  '''

  def __init__(self, index, depth, name):
    self.depth = depth
    self.index = index
    self.name = name
    self.start_tick = time.clock()
    self.ticks = 0

  def stop(self):
    self.ticks = time.clock() - self.start_tick

  def get_time(self):
    ''' Returns time in ms '''
    return self.ticks * 1000

  def __cmp__(self, other):
    return cmp(self.index, other.index)

class Stopwatch(object):
  '''
  Class used to measure application execution times.
  '''

  def __init__(self):
    '''
    Constructor
    '''
    self.event_ind = 0
    self.events = list()
    self.done_events = list()

  @staticmethod
  def get_instance():
    if not Stopwatch.__dict__.has_key('tdata') or not Stopwatch.tdata:
      Stopwatch.tdata = threading.local()
      Stopwatch.tdata.stopwatch = Stopwatch()
    return Stopwatch.tdata.stopwatch

  @staticmethod
  def start(event_name):
    Stopwatch.get_instance().__start_event(event_name)

  @staticmethod
  def stop():
    Stopwatch.get_instance().__stop_event()

  @staticmethod
  def pretty_print():
    return Stopwatch.get_instance().__pretty_print()

  @staticmethod
  def reset():
    ''' Resets stopwatch '''
    Stopwatch.tdata = None

  def __start_event(self, event_name):
    ''' Starts the event '''
    self.events.insert(0, Event(self.event_ind, len(self.events), event_name))
    self.event_ind += 1

  def __stop_event(self):
    ''' Stops the event '''
    if not self.events:
      return
    ev = self.events.pop(0)
    ev.stop()
    self.done_events.append(ev)

  def __pretty_print(self):
    buffer = StringIO()
    if (self.events):
      buffer.write('WARNING: same events have not been marked as closed, the summary might contain wrong data...\n')

    for ev in sorted(self.done_events):
      for i in range(0, ev.depth):
        buffer.write('  ')
      buffer.write('%s : %d ms\n' % (ev.name, ev.get_time()))
    return buffer.getvalue()
</pre></p>
<p>Now, when you have this code in one of your modules, you can simply type:</p>
<p><pre class="brush: python;">
Stopwatch.start('doing something')
do_something() # let's assume it takes 1s
Stopwatch.start('doing something else')
do_something_else() # let's assume it takes 2s
Stopwatch.stop()
Stopwatch.stop()
print Stopwatch.pretty_print()
</pre></p>
<p>and you should receive on the output:</p>
<p><pre class="brush: xml;">
do_something : 3000ms
  do_something_else : 2000ms
</pre></p>
<p>Most often you would like to measure the specific method execution time, so it may be boring to write Stopwatch.start as the first method&#8217;s line and Stopwatch.stop() as the last one and then remember to print stats somewhere. There&#8217;s a simple solution to this approach. I wrote a <em><strong>stopwatch</strong></em> method decorator. With it you can decorate the method you want to test, passing in arguments information if the log should be printed to the output. Here&#8217;s the code:</p>
<p><pre class="brush: python;">
def stopwatched(reset=False, logoutput=False):
&quot;&quot;&quot; Traces execution of the method &quot;&quot;&quot;
def decorator(fun):
def wrapper(*args, **kw):
if reset:
Stopwatch.reset()
Stopwatch.start(fun.func_name)
res = fun(*args, **kw)
Stopwatch.stop()
if (logoutput):
logging.info(&quot;\n&quot; + Stopwatch.pretty_print())
return res
return wrapper
return decorator
</pre></p>
<p>and example of usage (from Google&#8217;s Appengine):</p>
<p><pre class="brush: python;">
class MainHandler(webapp.RequestHandler):
  &quot;&quot;&quot;
  Index site
  &quot;&quot;&quot;
  @stopwatched(True, True)
  def get(self):
    validator = Validator()
    validator.is_valid(request.get('param'))
    self.response.out.write('TEST')

class Validator(object):

  @stopwatched()
  def is_valid(param):
    flag = do_some_logic() # 20ms
    return flag
</pre></p>
<p>After execution in your log output you should receive something like:</p>
<p><pre class="brush: xml;">
get: 21ms
  is_valid : 20ms
</pre></p>
<p>I hope you find this code useful. And if you have suggestions on how to optimize or improve it in any way, I will be happy to hear from you!</p>
<br />Posted in CodeProject, logging, python  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pytong.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pytong.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pytong.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pytong.wordpress.com&amp;blog=6978677&amp;post=3&amp;subd=pytong&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://pytong.wordpress.com/2009/03/16/timing-parts-of-the-application-code-in-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d7a0e28f7019863023fc2ce2a14fa1b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">pytong</media:title>
		</media:content>
	</item>
	</channel>
</rss>
