<?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/"
	>

<channel>
	<title>klainfo &#187; speed</title>
	<atom:link href="http://www.klainfo.com/tag/speed/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.klainfo.com</link>
	<description>Web2.0, HPC, Unix, and my mine.</description>
	<lastBuildDate>Thu, 09 Sep 2010 16:21:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>[Python] Optimize what needs optimizing?</title>
		<link>http://www.klainfo.com/2010/01/05/python-optimize-what-needs-optimizing/</link>
		<comments>http://www.klainfo.com/2010/01/05/python-optimize-what-needs-optimizing/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 01:50:51 +0000</pubDate>
		<dc:creator>klainfo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[optimizing]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>

		<guid isPermaLink="false">http://blog.klainfo.com/?p=549</guid>
		<description><![CDATA[ปกติแล้ว เวลาผมเขียนโปรแกรมจะถือคตินี้มาตลอด นั่นคือ Make it done, make it right, and then make it fast. blog นี้จะมาบอกว่า เราจะ opimize โปรแกรมที่เขียนด้วยภาษา python ได้อย่างไรบ้าง อย่างแรก ให้ติดตั้ง Python profiler ก่อน คลิก เพื่อดูว่าแต่ละ function ใช้เวลาในการทำงานนานเท่าไหร่ blog นี้ ผมจะสรุปจาก PerformanceTips ละกันครับ เลือก Data structure ให้เหมาะสม ใช้ Sorting ของ Python อ้างอิงจาก Comparing the well-known sorting algorithm ซึ่งผมเคยเทียบประสิทธิภาพไปแล้วว่า python sorting เร็วกว่าใครเพื่อน นอกจากนั้น Guido van]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.klainfo.com%2F2010%2F01%2F05%2Fpython-optimize-what-needs-optimizing%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.klainfo.com%2F2010%2F01%2F05%2Fpython-optimize-what-needs-optimizing%2F&amp;source=klainfo&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>ปกติแล้ว เวลาผมเขียนโปรแกรมจะถือคตินี้มาตลอด นั่นคือ</p>
<blockquote><p><strong>Make it done, make it right, and then make it fast.</strong></p></blockquote>
<p>blog นี้จะมาบอกว่า เราจะ opimize โปรแกรมที่เขียนด้วยภาษา python ได้อย่างไรบ้าง</p>
<p>อย่างแรก ให้ติดตั้ง Python profiler ก่อน <a href="http://klainfo.com/2010/01/05/identify-the-bottlenecks-by-python-profilers/">คลิก</a> เพื่อดูว่าแต่ละ function ใช้เวลาในการทำงานนานเท่าไหร่</p>
<p>blog นี้ ผมจะสรุปจาก <a href="http://wiki.python.org/moin/PythonSpeed/PerformanceTips">PerformanceTips</a> ละกันครับ</p>
<ol>
<li><strong>เลือก Data structure ให้เหมาะสม</strong></li>
<li><strong>ใช้ Sorting ของ Python</strong><br />
อ้างอิงจาก <a title="Comparing the well-known sorting algorithm" href="http://klainfo.com/2009/12/26/comparing-the-well-known-sorting-algorithm/">Comparing the well-known sorting algorithm</a> ซึ่งผมเคยเทียบประสิทธิภาพไปแล้วว่า python sorting เร็วกว่าใครเพื่อน นอกจากนั้น Guido van Rossum ยังแนะนำให้ใช้ comparator</li>
<li><strong>String Concatenation</strong><br />
<span style="color: #ff0000;"> หลีกเลี่ยง</span> (เอา string ใน list มา concat กัน)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = <span style="color: #483d8b;">&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> substring <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">list</span>:
    s += substring</pre></div></div>

<p><span style="color: #008000;">แนะนำ</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">s = <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#41;</span></pre></div></div>

<p><span style="color: #ff0000;">หลีกเลี่ยง</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">out = <span style="color: #483d8b;">&quot;&quot;</span> + head + prologue + query + tail + <span style="color: #483d8b;">&quot;&quot;</span></pre></div></div>

<p><span style="color: #008000;">แนะนำ</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">out = <span style="color: #483d8b;">&quot;%s%s%s%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>head, prologue, query, tail<span style="color: black;">&#41;</span></pre></div></div>

<p><span style="color: #008000;"><strong>แต่จะดูดีและเร็วขึ้นอีก ถ้าเขียนแบบนี้ (โฮก!! หล่อมาก++)</strong></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">out = <span style="color: #483d8b;">&quot;%(head)s%(prologue)s%(query)s%(tail)s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">locals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

</li>
<li><strong>Loops แนะนำให้ใช้ map-function</strong><br />
<span style="color: #ff0000;"> หลีกเลี่ยง</span> (แปลง string ใน list เป็น upper case)</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">newlist = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> word <span style="color: #ff7700;font-weight:bold;">in</span> oldlist:
    newlist.<span style="color: black;">append</span><span style="color: black;">&#40;</span>word.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><span style="color: #008000;">แนะนำ</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">newlist = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span>.<span style="color: black;">upper</span>, oldlist<span style="color: black;">&#41;</span></pre></div></div>

<p><span style="color: #008000;">หรือ</span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">newlist = <span style="color: black;">&#40;</span>s.<span style="color: black;">upper</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> s <span style="color: #ff7700;font-weight:bold;">in</span> oldlist<span style="color: black;">&#41;</span></pre></div></div>

</li>
<li><strong>Avoiding dot&#8230;<br />
<span style="font-weight: normal;">หลีกเลี่ยงการใช้ method chaining เช่น &#8216;AbCDe1234&#8242;.lower().count(&#8216;a&#8217;) เป็นต้น </span></strong></li>
<li><strong>Local Variable<br />
<span style="font-weight: normal;">Python สามารถ access local variable ได้เร็วกว่า global variable</span> </strong></li>
<li><strong>Initialize dictionary element</strong><br />
แนะนำให้ตั้งค่าเริ่มต้นให้กับ dictionary</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">wdict = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> word <span style="color: #ff7700;font-weight:bold;">in</span> words:
    <span style="color: #ff7700;font-weight:bold;">if</span> word <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> wdict:
        wdict<span style="color: black;">&#91;</span>word<span style="color: black;">&#93;</span> = <span style="color: #ff4500;">0</span>
    wdict<span style="color: black;">&#91;</span>word<span style="color: black;">&#93;</span> += <span style="color: #ff4500;">1</span></pre></div></div>

<p>หรือเขียนได้อีกแบบ</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">wdict = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> word <span style="color: #ff7700;font-weight:bold;">in</span> words:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        wdict<span style="color: black;">&#91;</span>word<span style="color: black;">&#93;</span> += <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyError</span>:
        wdict<span style="color: black;">&#91;</span>word<span style="color: black;">&#93;</span> = <span style="color: #ff4500;">1</span></pre></div></div>

</li>
<li><strong>import statement overhead</strong><br />
ทุกคำสั่ง import จะมี overhead เสมอ และหลีกเลี่ยงการใช้ import ภายใน function เช่น</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
    ...</pre></div></div>

</li>
<li><strong>Data aggregation</strong><br />
หลีกเลี่ยงการใช้ for loop ไปเรียก function<br />
หลีกเลี่ยง</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
x = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">def</span> doit1<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> x
    x = x + i
&nbsp;
<span style="color: #008000;">list</span> = <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span>
t = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">list</span>:
    doit1<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%.3f&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>-t<span style="color: black;">&#41;</span></pre></div></div>

<p>แนะนำ</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
x = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">def</span> doit2<span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> x
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">list</span>:
        x = x + i
&nbsp;
<span style="color: #008000;">list</span> = <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span>
t = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
doit2<span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%.3f&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>-t<span style="color: black;">&#41;</span></pre></div></div>

</li>
<li><strong>use xrange instead of range </strong></li>
</ol>
<p>โอ้ 10 ข้อแหนะ ถ้าทำได้หมดแล้วยังไม่เร็วขึ้น แนะนำให้ใช้ <a href="http://nattster.siamdev.net/2009/03/psyco-python/">Python Psyco</a> ละครับครับ</p>
<p class="facebook"><a href="http://www.facebook.com/share.php?u=http://www.klainfo.com/2010/01/05/python-optimize-what-needs-optimizing/" target="_blank"><img src="http://www.klainfo.com/wp-content/plugins/add-to-facebook-plugin/facebook_share_icon.gif" alt="Share on Facebook" title="Share on Facebook" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.klainfo.com/2010/01/05/python-optimize-what-needs-optimizing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Python] Identify the bottlenecks by Python profilers</title>
		<link>http://www.klainfo.com/2010/01/05/identify-the-bottlenecks-by-python-profilers/</link>
		<comments>http://www.klainfo.com/2010/01/05/identify-the-bottlenecks-by-python-profilers/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 00:56:33 +0000</pubDate>
		<dc:creator>klainfo</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[optimizing]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>

		<guid isPermaLink="false">http://blog.klainfo.com/?p=553</guid>
		<description><![CDATA[Python Profiler package เป็น package ไว้สำหรับ วิเคราะห์ประสิทธิภาพของโปรแกรมที่เขียนด้วยภาษา python เพื่อหา bottleneck หรือปัญหาคอขวดของโปรแกรมของเราว่าอยู่ตรงไหน Minimum-requirement: Python 2.6 or later [use profiler and pstats package] ถ้าเครื่องไหนไม่สามารถใช้งานได้ ให้ลงก่อน ด้วยคำสั่งดังกล่าว $ sudo aptitude install python-profiler ปกติแล้ว Python profilers จะมี standard library ชื่อว่า profile กับ cProfile ผมแนะนำให้ใช้ cProfile ดีกว่าครับ เพราะค่อนข้าง low-level กว่าและมี overhead ต่ำกว่าด้วยครับ ตัวอย่างการใช้งานทั่วๆไป import cProfile import pstats &#160; def foo&#40;&#41;:]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.klainfo.com%2F2010%2F01%2F05%2Fidentify-the-bottlenecks-by-python-profilers%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.klainfo.com%2F2010%2F01%2F05%2Fidentify-the-bottlenecks-by-python-profilers%2F&amp;source=klainfo&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Python Profiler package</strong> เป็น package ไว้สำหรับ วิเคราะห์ประสิทธิภาพของโปรแกรมที่เขียนด้วยภาษา python เพื่อหา bottleneck หรือปัญหาคอขวดของโปรแกรมของเราว่าอยู่ตรงไหน</p>
<p><strong>Minimum-requirement:</strong> Python 2.6 or later [use profiler and pstats package]</p>
<p>ถ้าเครื่องไหนไม่สามารถใช้งานได้ ให้ลงก่อน ด้วยคำสั่งดังกล่าว</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo aptitude install python-profiler</pre></div></div>

<p>ปกติแล้ว Python profilers จะมี standard library ชื่อว่า profile กับ cProfile ผม<strong>แนะนำให้ใช้ cProfile </strong>ดีกว่าครับ เพราะค่อนข้าง low-level กว่าและมี overhead ต่ำกว่าด้วยครับ</p>
<p><strong>ตัวอย่างการใช้งานทั่วๆไป</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> cProfile
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">pstats</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    ...
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    cProfile.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo()'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>วิธีใช้งานคือ เรียกคำสั่ง  cProfile.run(&#8216; ชื่อฟังก์ชั่น &#8216;) แค่นั้นเองครับ ง่ายมาก</p>
<p><strong>ตัวอย่างการใช้งานเมื่อมีการส่ง parameter ให้ function</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> cProfile
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">pstats</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">&#40;</span>bar<span style="color: black;">&#41;</span>:
    ...
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    cProfile.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo()'</span>,<span style="color: black;">&#91;</span>bar<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>วิธีใช้งานคือ เรียกคำสั่ง  cProfile.run(&#8216; ชื่อฟังก์ชั่น &#8216;, list ของ parameter )</p>
<p>ตัวอย่างของผลลัพท์</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">      2706 function calls (2004 primitive calls) in 4.504 CPU seconds
&nbsp;
Ordered by: standard name
&nbsp;
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     2    0.006    0.003    0.953    0.477 pobject.py:75(save_objects)
  43/3    0.533    0.012    0.749    0.250 pobject.py:99(evaluate)
 ...</pre></div></div>

<blockquote><p>2706 function calls (2004 primitive calls) in 4.504 CPU seconds</p>
<p>หมายถึง มีการเรียก function 2706 ครั้ง ภายในเวลา 4.504 วินาที สำหรับ primitive calls หมายถึง จำนวนการเรียกฟังก์ชั่นแบบไม่ recursive นั่นคือ ถ้ามีการ recursive primitive จะนับแค่ 1 ครั้งเท่านั้น</p></blockquote>
<blockquote><p>ncalls หมายถึง จำนวนครั้งที่เรียก function นั้นๆๆ</p>
<p>tottime หมายถึง ปริมาณเวลาทั้งหมด ที่ใช้ในการเรียก function ทั้งหมด</p>
<p>percall หมายถึง สัดส่วน ncall/tottime</p>
<p>cumtime (cumulative time) เวลาที่ใช้ใน function นั้นๆ</p>
<p>percall หมายถึง สัดส่วน primitive call/cumulative time</p>
<pre>filename:lineno(function) ระบุ ชื่อไฟล์ บรรทัดที่? และชื่อ function นั้นๆ</pre>
</blockquote>
<p>สำหรับรายละเอียดเพิ่มเติมสามารถดูได้จาก <a href="http://docs.python.org/library/profile.html">http://docs.python.org/library/profile.html</a></p>
<p class="facebook"><a href="http://www.facebook.com/share.php?u=http://www.klainfo.com/2010/01/05/identify-the-bottlenecks-by-python-profilers/" target="_blank"><img src="http://www.klainfo.com/wp-content/plugins/add-to-facebook-plugin/facebook_share_icon.gif" alt="Share on Facebook" title="Share on Facebook" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.klainfo.com/2010/01/05/identify-the-bottlenecks-by-python-profilers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
