[Pyrex] Pyrex method 10x slower than Python, any hints why?

John Machin sjmachin at lexicon.net
Thu Jun 1 01:17:35 UTC 2006


On 1/06/2006 8:40 AM, David Chiang wrote:
> Hello all, when I compare this method
>    
>      def estimate(self, r):
>          sum = 0.0
>          for i in xrange(r.e.arity()+1):
>             cost = lookup_words(self.ngram, None, [r.e.getchunk(i)], 1, 0, self.mapdigits, self.ceiling) 
>              sum = sum + cost
>                                                                                   
>          return sum

I would have expected that it would not be worth the bother of rewriting 
that function in Pyrex -- e.g. cdef'ing i and cost doesn't help much as 
the values of i and cost have to be converted each time around the loop. 
Instead, I would experiment with tweaking up the Python somewhat, like 
below ... however again the time saved will probably be minute compared 
to the cost of just calling lookup_words() plus whatever is going on 
inside it.

def estimate(self, r):
     total = 0.0 # sum is a built-in function
     ngram = self.ngram
     getchunk = r.e.getchunk
     mapdigits = self.mapdigits
     ceiling = self.ceiling
     for i in xrange(r.e.arity()+1):
         total += lookup_words(
             ngram, None, [getchunk(i)], 1, 0, mapdigits, ceiling
             )
     return total
>    
>    against a Pyrex equivalent
>    
>        def estimate(self, rule.Rule r):
>            cdef float sum, cost
>            cdef int i
>            sum = 0.0
>            for i from 0 <= i <= r.e.arity():
>               cost = lookup_words(self.ngram, None, [r.e.getchunk(i)], 1, 0, self.mapdigits, self.ceiling) 
>                sum = sum + cost
>                                                                                   
>            return sum
>  
>  where the containing class is a user class and self.ngram, r, and r.e are instances of extension types, the Python version runs, it would seem, 10 times faster. I've looked a bit at the generated C code (attached) and didn't see anything obviously wrong; does anyone have any hints about what may be going on? I realize this is kind of a vague question but any pointers for further testing would be appreciated. Thanks in advance!
>    

I've had a quick look at the C code, but can't see anything obvious. You 
may wish to apply dis.dis() to your Python method and see what Python is 
doing. Another approach might be to start with a Pyrex method that is 
exactly the same as your Python method, measure it, then introduce Pyrex 
changes one at a time.

HTH,
John



More information about the Pyrex mailing list