CINXE.COM
Launchpad Blog
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="Blog posts from the Launchpad team" /> <title>Launchpad Blog</title> <link href="https://blog.launchpad.net/wp-content/themes/launchpad/style.css" rel="stylesheet" type="text/css" /> <link rel="shortcut icon" href="https://launchpad.net/@@/launchpad" /> <script type="text/javascript" src="https://blog.launchpad.net/wp-content/themes/launchpad/js/mootools-1.2-core.js"></script> <script type="text/javascript" src="https://blog.launchpad.net/wp-content/themes/launchpad/js/funcs.js"></script> <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-12833497-3']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> </head> <body> <!-- Header --> <div id="header"> <a href="/wp-admin" style="float:right; top: 2px;">Log in</a> <div id="finder"> <input type="search" accesskey="s" value="Search blog archives" name="s" id="s" /> <input type="hidden" name="blog_url" id="blog_url" value="https://blog.launchpad.net" /> <a href="https://blog.launchpad.net/feed" title="RSS Feed for Blog Entries"><img src="https://blog.launchpad.net/wp-content/themes/launchpad/images/rss.png" alt="RSS Feed" /></a> </div> <h1><a href="https://blog.launchpad.net" class="header-link"><img src="https://blog.launchpad.net/wp-content/themes/launchpad/images/logo.png" /><span class="logotext"> launchpad</span><strong>blog</strong></a></h1> </div> <div id="content" class="widecolumn"> <div class="navigation"> « <a href="https://blog.launchpad.net/bug-tracking/new-bugs-status-opinion" rel="prev">New Launchpad Bugs Status: Opinion</a> <a href="https://blog.launchpad.net/general/launchpad-epic-2010-photo" rel="next">Launchpad EPIC 2010 photo</a> » </div> <div class="post" id="post-1626"> <h2> <a href="https://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients" rel="bookmark" title="Permanent Link: Three tips for faster launchpadlib api clients">Three tips for faster launchpadlib api clients</a> </h2> <div class="entry"> <p>Three tips from <a href="http://launchpad.net/~leonardr">Leonard’s</a> lightning talk in Prague about writing faster <a href="https://help.launchpad.net/API/launchpadlib#preview">Launchpadlib</a> API clients:</p> <p><b>1. Use the latest launchpadlib.</b> It gets faster from one release to the next. (The versions in the current Ubuntu release should be fine; otherwise run from the <a href="https://code.edge.launchpad.net/~lazr-developers/launchpadlib/trunk">branch</a> or the latest <a href="https://launchpad.net/launchpadlib/+download">tarball</a>.)</p> <p><b>2. Profile:</b></p> <pre> import httplib2 httplib2.debuglevel = 1 </pre> <p>will show each http request and response, so that you can see what’s taking time.</p> <p><b>3. Fetch objects only once:</b></p> <p>Don’t do this:</p> <pre> if bug.person is not None: print bug.person.name </pre> <p>instead</p> <pre> p = bug.person if p is not None: print p.name </pre> <p>In the first case, the client may fetch the Person object twice. (We may fix this in future.)</p> <p>Tags: <a href="https://blog.launchpad.net/tag/api" rel="tag">API</a>, <a href="https://blog.launchpad.net/tag/clients" rel="tag">clients</a>, <a href="https://blog.launchpad.net/tag/front-page" rel="tag">front-page</a>, <a href="https://blog.launchpad.net/tag/performance" rel="tag">Performance</a>, <a href="https://blog.launchpad.net/tag/tip" rel="tag">tip</a></p> <p class="postmetadata alt"> <small>This entry was posted by <strong>Martin Pool</strong> on Wednesday, July 14th, 2010 at 1:30 pm and is filed under <a href="https://blog.launchpad.net/category/api" rel="category tag">API</a>. You can follow any responses to this entry through the <a href="https://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients/feed">RSS 2.0</a> feed. You can <a href="#respond">leave a response</a>, or <a href="https://blog.launchpad.net/api/three-tips-for-faster-launchpadlib-api-clients/trackback" rel="trackback">trackback</a> from your own site. </small> </p> </div> </div> <!-- You can start editing here. --> <h3 id="comments">7 Responses to “Three tips for faster launchpadlib api clients”</h3> <ol class="commentlist"> <li class="alt" id="comment-40029"> <img alt='' src='https://secure.gravatar.com/avatar/ee7c3409177a20f610a6d2dc9a9d2347?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/ee7c3409177a20f610a6d2dc9a9d2347?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite>Markus Korn</cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40029" title="">July 14th, 2010 at 2:28 pm</a> </small> <p>Another trick is to use Uris instead of objects in method arguments, for example</p> <p>In [6]: timeit zeitgeist.searchTasks(assignee=str(launchpad._root_uri) + “~thekorn”)<br /> 1 loops, best of 3: 337 ms per loop</p> <p>In [7]: timeit zeitgeist.searchTasks(assignee=launchpad.people[“thekorn”])<br /> 1 loops, best of 3: 537 ms per loop</p> <p>The api doc at [0] tells you how the uri of a certain object has to llok like.</p> <p>[0] <a href="https://launchpad.net/+apidoc/" rel="nofollow ugc">https://launchpad.net/+apidoc/</a></p> </li> <li id="comment-40030"> <img alt='' src='https://secure.gravatar.com/avatar/25f341c0a0898629a946697d905e8672?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/25f341c0a0898629a946697d905e8672?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite>james</cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40030" title="">July 14th, 2010 at 2:41 pm</a> </small> <p>For a read-only script of mine trawling bugs, I saw a roughly 5-times speed increase by wrapping my bug-task objects in this below – a very blunt caching mechanism:</p> <pre> class LPWrap: "Simple wrapper Cache-Proxy for LP objects" def __init__(self, lpObj): self.lpObj = lpObj def __getattr__(self, attr): result = getattr(self.lpObj, attr) if result.__class__.__name__ == "Entry": result = LPWrap(result) setattr(self, attr, result) return result </pre> <p>[edited to fix formatting — mbp]</p> </li> <li class="alt" id="comment-40031"> <img alt='' src='https://secure.gravatar.com/avatar/25f341c0a0898629a946697d905e8672?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/25f341c0a0898629a946697d905e8672?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite>james</cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40031" title="">July 14th, 2010 at 2:43 pm</a> </small> <p>oh dear – indentation not preserved :(. the if … “Entry” only acts on the single succeeding line. I think everything else is relatively unambiguous</p> </li> <li id="comment-40033"> <img alt='' src='https://secure.gravatar.com/avatar/dfeb8f8baea10eef96b1514c9223768d?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/dfeb8f8baea10eef96b1514c9223768d?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite><a href='http://blog.smartcube.co.za' rel='external nofollow ugc' class='url'>drubin</a></cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40033" title="">July 14th, 2010 at 9:40 pm</a> </small> <p>“May fix”</p> <p>It should be the API’s responsibility to handle caching. Else you are coding around the core problem instead of fixing it. Passing references all around the place to try limit your http calls is silly. The API is supposed to be the interface to LP not just a dumb layer on top of http.</p> <p>It should at the very least be an option that is enabled by default. Since most people that use the API will be small time fish and the bigger fish would simple know the API well enough to turn off the caching and handle it internally.</p> <p>Just my 2cents.</p> </li> <li class="alt" id="comment-40037"> <img alt='' src='https://secure.gravatar.com/avatar/5347c683b6963f418d1b16c65917bf3f?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/5347c683b6963f418d1b16c65917bf3f?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite><a href='https://login.launchpad.net/+id/s3nhXMJ' rel='external nofollow ugc' class='openid_link url'>Martin Pool</a></cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40037" title="">July 15th, 2010 at 9:21 am</a> </small> <p>@drubin I agree we should have at least a sensible minimal level of caching, and we need the API to at least take the concept of caching into account. I can imagine over-aggressive caching also being confusing to clients.</p> </li> <li id="comment-40044"> <img alt='' src='https://secure.gravatar.com/avatar/c0db47186e1ed8714583e897e6faf6da?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/c0db47186e1ed8714583e897e6faf6da?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite><a href='http://murraytwins.com/blog/' rel='external nofollow ugc' class='url'>Brian Murray</a></cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40044" title="">July 20th, 2010 at 7:58 pm</a> </small> <p>Latest version of launchpadlib is rather vague – talking with Leonard about this he really meant the version of launchpadlib in Maverick which is still under active development.</p> </li> <li class="alt" id="comment-40050"> <img alt='' src='https://secure.gravatar.com/avatar/c0db47186e1ed8714583e897e6faf6da?s=32&d=blank&r=g' srcset='https://secure.gravatar.com/avatar/c0db47186e1ed8714583e897e6faf6da?s=64&d=blank&r=g 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy'/> <cite><a href='http://murraytwins.com/blog/' rel='external nofollow ugc' class='url'>Brian Murray</a></cite> Says: <br /> <small class="commentmetadata"><a href="#comment-40050" title="">July 23rd, 2010 at 7:15 pm</a> </small> <p>Working with Leonard I’ve included the performance improvement patches into a Lucid version of the package which can be found in my PPA – <a href="https://edge.launchpad.net/~brian-murray/+archive/ppa" rel="nofollow ugc">https://edge.launchpad.net/~brian-murray/+archive/ppa</a>. This should also make its way into Lucid updates and you can follow bug 607947 regarding that.</p> </li> </ol> <h3 id="respond">Leave a Reply</h3> <form action="https://blog.launchpad.net/wp-comments-post.php" method="post" id="commentform"> <p><input type="text" name="author" id="author" value="" size="22" tabindex="1" /> <label for="author"><small>Name </small></label></p> <p><input type="text" name="email" id="email" value="" size="22" tabindex="2" /> <label for="email"><small>Mail (will not be published) </small></label></p> <p><input type="text" name="url" id="url" value="" size="22" tabindex="3" /> <label for="url"><small>Website</small></label></p> <!--<p><small><strong>XHTML:</strong> You can use these tags: <code><a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> </code></small></p>--> <p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p> <p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" /> <input type="hidden" name="comment_post_ID" value="1626" /> </p> <p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="88f6ff42aa" /></p><p style="display: none !important;"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="74"/><script>document.getElementById( "ak_js_1" ).setAttribute( "value", ( new Date() ).getTime() );</script></p> </form> </div> <div id="footer"> <p> <a href="https://help.launchpad.net/Legal">Terms of use</a> | <a href="https://launchpad.net/feedback">Help improve Launchpad</a> | <a href="https://launchpad.net/faq">FAQ</a> </p> <p><a rel="license" href="http://creativecommons.org/licenses/by/2.0/uk/"> <span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Launchpad Blog</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://canonical.com/" property="cc:attributionName" rel="cc:attributionURL">Canonical Ltd</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/2.0/uk/">Creative Commons Attribution 2.0 UK: England & Wales License</a>. <img alt="Creative Commons License" style="border-width:0;vertical-align:middle;" src="https://i.creativecommons.org/l/by/2.0/uk/80x15.png" /></a></p> <p>© 2004-2019 <a href="https://canonical.com/" target="_blank">Canonical Limited.</a></p> </div>