can't wait to try beta5 out.<br><br><div><span class="gmail_quote">2006/3/18, Dino Viehland &lt;<a href="mailto:dinov@exchange.microsoft.com">dinov@exchange.microsoft.com</a>&gt;:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The good news this is basically the same issue.&nbsp;&nbsp;The better news is I've got a fix that gets us performance that's pretty much equal to CPython that will be in Beta 5 for both this and the other generator case.<br><br>Thanks for reporting these.&nbsp;&nbsp;If you (or anyone else) has other issues they'd like to point out now's a great time, keep them coming!
<br><br><br>Do you want to help develop Dynamic languages on CLR? (<a href="http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038">http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038
</a>)<br><br>-----Original Message-----<br>From: <a href="mailto:users-bounces@lists.ironpython.com">users-bounces@lists.ironpython.com</a> [mailto:<a href="mailto:users-bounces@lists.ironpython.com">users-bounces@lists.ironpython.com
</a>] On Behalf Of Anthony Tarlano<br>Sent: Thursday, March 16, 2006 11:45 PM<br>To: Discussion of IronPython<br>Subject: Re: [IronPython] Generator Performance (IronPython vs. CPython(<br><br>Dino,<br><br>Here is another performance example to provide more &quot;food for thought&quot;.
<br><br>This is the second example from the article. In this example a<br>comparison between a for loop and another generator based thread<br>scheduler performing the same operations is made.<br><br>Here is the code:<br><br>
# overhead.py<br><br>import time<br><br>TIMES = 100000<br><br>threads = list()<br><br>def stringops():<br>&nbsp;&nbsp;&nbsp;&nbsp;for n in xrange(TIMES):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.upper()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.lower()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.replace('a','A')<br><br>def scheduler():<br>&nbsp;&nbsp;&nbsp;&nbsp;for n in xrange(TIMES):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for thread in threads: thread.next()<br><br>def upper():
<br>&nbsp;&nbsp;&nbsp;&nbsp;while 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.upper()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield None<br><br>def lower():<br>&nbsp;&nbsp;&nbsp;&nbsp;while 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.lower
()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield None<br><br>def replace():<br>&nbsp;&nbsp;&nbsp;&nbsp;while 1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = &quot;Mary had a little lamb&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = s.replace('a','A')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield None<br><br>if __name__=='__main__':<br>&nbsp;&nbsp;&nbsp;&nbsp;start = time.clock
()<br>&nbsp;&nbsp;&nbsp;&nbsp;stringops()<br>&nbsp;&nbsp;&nbsp;&nbsp;looptime = time.clock()-start<br>&nbsp;&nbsp;&nbsp;&nbsp;print &quot;LOOP TIME:&quot;, looptime<br><br>&nbsp;&nbsp;&nbsp;&nbsp;threads.append(upper())<br>&nbsp;&nbsp;&nbsp;&nbsp;threads.append(lower())<br>&nbsp;&nbsp;&nbsp;&nbsp;threads.append(replace())<br>&nbsp;&nbsp;&nbsp;&nbsp;start = time.clock
()<br>&nbsp;&nbsp;&nbsp;&nbsp;scheduler()<br>&nbsp;&nbsp;&nbsp;&nbsp;threadtime = time.clock()-start<br>&nbsp;&nbsp;&nbsp;&nbsp;print &quot;THREAD TIME:&quot;, threadtime<br><br><br>And here are the pitiful results for IronPython vs CPython:<br><br>sh-2.04$ python overhead.py<br>LOOP TIME: 
0.326167711259<br>THREAD TIME: 0.548508818858<br><br>sh-2.04$ IronPythonConsole overhead.py<br>LOOP TIME: 0.734375<br>THREAD TIME: 1.046875<br><br>Anthony<br><br>On 3/16/06, Dino Viehland &lt;<a href="mailto:dinov@exchange.microsoft.com">
dinov@exchange.microsoft.com</a>&gt; wrote:<br>&gt; Thanks for the report of the perf issue.<br>&gt;<br>&gt; We are actually actively working on improving the perf of IronPython for the next release so I've gone ahead and filed a bug to make sure we look into this issue.&nbsp;&nbsp;Hopefully we'll have something more concrete to let you know about this scenario soon, but unfortunately it's not one of the issues we've fixed so far.
<br>&gt;<br>&gt;<br>&gt;<br>&gt; Do you want to help develop Dynamic languages on CLR? (<a href="http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038">http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038
</a>)<br>&gt; -----Original Message-----<br>&gt; From: <a href="mailto:users-bounces@lists.ironpython.com">users-bounces@lists.ironpython.com</a> [mailto:<a href="mailto:users-bounces@lists.ironpython.com">users-bounces@lists.ironpython.com
</a>] On Behalf Of Anthony Tarlano<br>&gt; Sent: Thursday, March 16, 2006 1:24 PM<br>&gt; To: Discussion of IronPython<br>&gt; Subject: [IronPython] Generator Performance (IronPython vs. CPython(<br>&gt;<br>&gt; Hi,<br>&gt;
<br>&gt; I investigating the use of&nbsp;&nbsp;lightweight threads, so I was reading<br>&gt; &quot;Charming Python #b7: Implementing weightless threads with Python<br>&gt; generators. by David Mertz, Ph.D.&quot;<br>&gt;<br>&gt; The first example 
microthreads.py is about the simplest weightless<br>&gt; thread scheduler one could choose. Here is the code:<br>&gt;<br>&gt; -------------------------------------------------------------------------------------------------------------------
<br>&gt; # microthreads.py<br>&gt;<br>&gt; import sys, time<br>&gt;<br>&gt; threads = []<br>&gt; TOTALSWITCHES = 10**6<br>&gt; NUMTHREADS&nbsp;&nbsp;&nbsp;&nbsp;= 10**5<br>&gt;<br>&gt; def null_factory():<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; def empty():<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while 1: yield None
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; return empty()<br>&gt;<br>&gt; def quitter():<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; for n in xrange(TOTALSWITCHES/NUMTHREADS):<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield None<br>&gt;<br>&gt; def scheduler():<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; global threads<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; try:<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while 1:<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for thread in threads: thread.next()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; except StopIteration:<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br>&gt;<br>&gt; if __name__ == &quot;__main__&quot;:<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; for i in range(NUMTHREADS):
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threads.append(null_factory())<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; threads.append(quitter())<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; starttime = time.clock()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; scheduler()<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;TOTAL TIME:&nbsp;&nbsp;&nbsp;&nbsp;&quot;, time.clock()-starttime<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;TOTAL SWITCHES:&quot;, TOTALSWITCHES
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;TOTAL THREADS: &quot;, NUMTHREADS<br>&gt;<br>&gt; -------------------------------------------------------------------------------------------------------------------<br>&gt;<br>&gt; After running the example on CPython the following results are printed:
<br>&gt;<br>&gt; sh-2.04$ python microthreads.py<br>&gt; TOTAL TIME:&nbsp;&nbsp;&nbsp;&nbsp; 0.718205526121<br>&gt; TOTAL SWITCHES: 1000000<br>&gt; TOTAL THREADS:&nbsp;&nbsp;100000<br>&gt;<br>&gt; After running the example on IronPython the following results are printed:
<br>&gt;<br>&gt; sh-2.04$ IronPythonConsole microthreads.py<br>&gt; TOTAL TIME:&nbsp;&nbsp;&nbsp;&nbsp; 1.49999237061<br>&gt; TOTAL SWITCHES: 1000000<br>&gt; TOTAL THREADS:&nbsp;&nbsp;100000<br>&gt;<br>&gt; This shows that IronPython took 0.781786844489
 more then CPython to do<br>&gt; the same switching between generators in this example. I was quites<br>&gt; surprise to see this since that's more then double the time of<br>&gt; CPython.<br>&gt;<br>&gt; Thus, the question is whether this performance result is acceptable to
<br>&gt; the IronPython team.<br>&gt;<br>&gt; Thanks,<br>&gt;<br>&gt; Anthony<br>&gt; _______________________________________________<br>&gt; users mailing list<br>&gt; <a href="mailto:users@lists.ironpython.com">users@lists.ironpython.com
</a><br>&gt; <a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com">http://lists.ironpython.com/listinfo.cgi/users-ironpython.com</a><br>&gt; _______________________________________________<br>&gt; users mailing list
<br>&gt; <a href="mailto:users@lists.ironpython.com">users@lists.ironpython.com</a><br>&gt; <a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com">http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
</a><br>&gt;<br>_______________________________________________<br>users mailing list<br><a href="mailto:users@lists.ironpython.com">users@lists.ironpython.com</a><br><a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com">
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com</a><br>_______________________________________________<br>users mailing list<br><a href="mailto:users@lists.ironpython.com">users@lists.ironpython.com</a><br><a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com">
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com</a><br></blockquote></div><br>