<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2912" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>Hi</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>First of all thanks to Greg for Pyrex (which I have
come to very recently and which will certainly make wrapping libraries
easier)</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I've been looking for an alternative to Psyco for
distributing Python apps to other platforms than Win32 - however (while not
being in general a 'speed' junkie) I don't want to sacrifice
performance.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I've been trying Pyrex out on a small text search
programme which uses the Boyer-Moore algorithm and which I have adapted to
search for all occurrences of a string in the given text.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>With algorithmic improvements I managed something
like a 10 fold increase in speed performance and Psyco gives me another 10 fold
increase. I've read all the tips and tricks re: Pyrex I can find and tried
to implement them but I can't seem to replicate the performance enhancement over
Psyco which the Pyrex test suite demonstrates - in fact Psyco wins hands down
every time.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Am I (as a newcomer) doing soething obviously wrong
or is there something about this code that means one wouldn't expect
particularly fast execution???</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Thanks</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Phil</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>This is my pyx file:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Courier size=2>-----------------------------------</FONT></DIV>
<DIV><FONT face=Courier size=2></FONT> </DIV>
<DIV>
<P><FONT face=Arial size=2>cdef extern from "Python.h":</FONT></P>
<P><FONT face=Arial size=2> cdef object
PySequence_GetItem(object o, int i)</FONT></P>
<P><FONT face=Arial size=2> cdef int PyList_Append(object
list, object item)</FONT></P>
<P><FONT face=Arial size=2> #cdef object
PySequence_GetSlice(object o, int i1, int i2)</FONT></P>
<P><FONT face=Arial size=2> cdef int PyList_SET_ITEM(object
PyList, int idx, object obj) except -1</FONT></P>
<P><FONT face=Arial size=2> cdef void *PyList_GET_ITEM(object
PyList, int idx) # except NULL</FONT></P>
<P><FONT face=Arial size=2> cdef void Py_INCREF(void
*)</FONT></P>
<P><FONT face=Arial size=2> cdef int PySequence_Size(object
o)</FONT></P>
<P><FONT face=Arial size=2> ctypedef struct
PyObject</FONT></P>
<P><FONT face=Arial size=2>cdef int setListItem(object PyList, int idx, object
obj) except -1:</FONT></P>
<P><FONT face=Arial size=2> Py_INCREF(<PyObject
*>obj)</FONT></P>
<P><FONT face=Arial size=2> PyList_SET_ITEM(PyList, idx,
obj)</FONT></P>
<P><FONT face=Arial size=2>cdef object getListItem(object PyList, int
idx):</FONT></P>
<P><FONT face=Arial size=2> return
<object>PyList_GET_ITEM(PyList, idx)</FONT></P>
<P><FONT face=Arial size=2>def findall(pattern, text): #adapted to find all
occurences of pattern in text</FONT></P>
<P><FONT face=Arial size=2> cdef int m,j</FONT></P>
<P><FONT face=Arial size=2> cdef long n,k,i</FONT></P>
<P><FONT face=Arial size=2> m=len(pattern) #once
only</FONT></P>
<P><FONT face=Arial size=2> n=len(text) #once only</FONT></P>
<P><FONT face=Arial size=2> skip=[] #once only</FONT></P>
<P><FONT face=Arial size=2> for k from
0<=k<256:</FONT></P>
<P><FONT face=Arial size=2> #for k in range(256):</FONT></P>
<P><FONT face=Arial size=2>
PyList_Append(skip,m)</FONT></P>
<P><FONT face=Arial size=2> #skip.append(m)
#once only</FONT></P>
<P><FONT face=Arial size=2> for k from
0<=k<m-1:</FONT></P>
<P><FONT face=Arial size=2> #for k in
range(m-1):</FONT></P>
<P><FONT face=Arial size=2>
setListItem(skip,ord(PySequence_GetItem(pattern,k)),m-k-1)</FONT></P>
<P><FONT face=Arial size=2>
#skip[ord(pattern[k])]=m-k-1 #once only</FONT></P>
<P><FONT face=Arial size=2> result=[] #once only</FONT></P>
<P><FONT face=Arial size=2> while True:</FONT></P>
<P><FONT face=Arial size=2> if m>n: #if
pattern is longer than (remaining) text</FONT></P>
<P><FONT face=Arial size=2>
return result #can't match more so return matches
found</FONT></P>
<P><FONT face=Arial size=2> k=m-1 #need to
reset each time - k is offset into text</FONT></P>
<P><FONT face=Arial size=2> while
k<n:</FONT></P>
<P><FONT face=Arial size=2>
j=m-1 #j is offset to last char of pattern</FONT></P>
<P><FONT face=Arial size=2>
i=k #i offset into text where backward search
commences</FONT></P>
<P><FONT face=Arial
size=2> while
j >= 0 and PySequence_GetItem(text,i) ==
PySequence_GetItem(pattern,j):</FONT></P>
<P><FONT face=Arial
size=2> #while
j>=0 and text[i]==pattern[j]: #keep matching chars backwards</FONT></P>
<P><FONT face=Arial
size=2>
j=j-1</FONT></P>
<P><FONT face=Arial
size=2>
i=i-1</FONT></P>
<P><FONT face=Arial
size=2> if
j==-1: #whole pattern was matched</FONT></P>
<P><FONT face=Arial
size=2>
PyList_Append(result,i+1)</FONT></P>
<P><FONT face=Arial
size=2>
#result.append(i+1) #save the location of this match</FONT></P>
<P><FONT face=Arial
size=2> k=k+getListItem(skip,ord(PySequence_GetItem(text,k)))</FONT></P>
<P><FONT face=Arial
size=2> #k=k+skip[ord(text[k])]</FONT></P>
<P><FONT face=Arial size=2> n=n-k
#update n to number of chars remaining in text</FONT></P>
<P><FONT face=Arial size=2> return
result</FONT></P></DIV></BODY></HTML>