<!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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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.&nbsp; 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>&nbsp;</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>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Thanks</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Phil</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>This is my pyx file:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier size=2>-----------------------------------</FONT></DIV>
<DIV><FONT face=Courier size=2></FONT>&nbsp;</DIV>
<DIV>
<P><FONT face=Arial size=2>cdef extern from "Python.h":</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef object 
PySequence_GetItem(object o, int i)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef int PyList_Append(object 
list, object item)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; #cdef object 
PySequence_GetSlice(object o, int i1, int i2)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef int PyList_SET_ITEM(object 
PyList, int idx, object obj) except -1</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef void *PyList_GET_ITEM(object 
PyList, int idx) # except NULL</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef void Py_INCREF(void 
*)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef int PySequence_Size(object 
o)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp; Py_INCREF(&lt;PyObject 
*&gt;obj)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp; return 
&lt;object&gt;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>&nbsp;&nbsp;&nbsp; cdef int m,j</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; cdef long n,k,i</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; m=len(pattern) #once 
only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; n=len(text) #once only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; skip=[] #once only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; for k from 
0&lt;=k&lt;256:</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; #for k in range(256):</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
PyList_Append(skip,m)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #skip.append(m) 
#once only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;for k from 
0&lt;=k&lt;m-1:</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;#for k in 
range(m-1):</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
setListItem(skip,ord(PySequence_GetItem(pattern,k)),m-k-1)</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
#skip[ord(pattern[k])]=m-k-1 #once only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; result=[] #once only</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; while True:</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if m&gt;n: #if 
pattern is longer than (remaining) text</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; return result #can't match more so return matches 
found</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; k=m-1 #need to 
reset each time - k is offset into text</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while 
k&lt;n:</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; j=m-1 #j is offset to last char of pattern</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; i=k #i offset into text where backward search 
commences</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while 
j &gt;= 0 and PySequence_GetItem(text,i) == 
PySequence_GetItem(pattern,j):</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#while 
j&gt;=0 and text[i]==pattern[j]: #keep matching chars backwards</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
j=j-1</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
i=i-1</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 
j==-1: #whole pattern was matched</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
PyList_Append(result,i+1)</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
#result.append(i+1) #save the location of this match</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k=k+getListItem(skip,ord(PySequence_GetItem(text,k)))</FONT></P>
<P><FONT face=Arial 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#k=k+skip[ord(text[k])]</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n=n-k 
#update n to number of chars remaining in text</FONT></P>
<P><FONT face=Arial size=2>&nbsp;&nbsp;&nbsp; return 
result</FONT></P></DIV></BODY></HTML>