<div class="gmail_quote">I'm making the presumption that you are using Python 2.x in my notes.</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Thu, Jun 2, 2011 at 3:07 PM, Keir Rice <span dir="ltr"><<a href="mailto:keirrice@gmail.com">keirrice@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi All,<br>
<br>
The following function was showing up in my profiles as a large bottle neck:<br>
<br>
# Slow version<br>
def RMSBand(self, histogram):<br>
"""Calculates the root-mean-squared value for the given colour stream histogram."""<br>
intermediateResult = map(lambda (i, h): h*(i**2), zip(histogram, range(255)))<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> totalSum = sum(intermediateResult)<br>
<br></blockquote><div><div>range(255) will create a list containing 255 elements.</div><div>The zip will also create a list containing 255 elements.</div><div>map will also create a list containing 255 elements.</div><div>
The lambda is adding both function definition (which is probably very minimal) and 255 function calls (which may be slower)</div></div><div>You are also iterating over the lists a total of 3 times (one for zip, one for map, one for sum) than the once in your later version.</div>
<div><br></div><div><div>It may be that the following two lines are faster than your two lines, in which case its the list creations:</div><div>import itertools</div><div>totalSum = sum(itertools.imap(lambda (h, i): h*(i**2), enumerate(histogram))</div>
</div><div><br></div><div>If the function call is significant, the following will be even faster:</div><div>totalSum = sum(h*(i**2) for (i, h) in enumerate(histogram))</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
# calculate rms<br>
return math.sqrt(totalSum / self.Area())<br>
<br>
So after a bit of trial and error I came up with the following function which is a lot faster:<br>
<br>
# Fast version<br>
def RMSBand(self, histogram):<br>
"""Calculates the root-mean-squared value for the given colour stream histogram."""<br>
totalSum = 0<br>
for i, h in enumerate(histogram):<br>
totalSum += h*(i**2)<br>
<br>
# calculate rms<br>
return math.sqrt(totalSum / self.Area())<br>
<br>
My question is why is the second method so much faster?<br>
Is it the removal of the extra function calls?<br>
Is it skipping the creation of a list?<br></blockquote><div><br></div><div>My guess is its a combination of the removal of 255 function calls and the generation of three 255-item lists (not just the one you are implying you know about).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Do the basic arithmetic operators get pushed up into C code?<br>
<br>
Any insights into the whats really happening behind the scenes would be appreciated.<br>
<br>
Keir<br>
<font color="#888888">--<br>
<a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
</font></blockquote></div><br>