June 2007 Archives
Tue Jun 12 11:03:47 ART 2007
Unsucessfull use of pyrex
A weeks ago a was doing some performance test to [pyrex]. I made an application using genetic algorithms with a very time consuming fitness function in python and I wanted to improve the overall performance of the application. That's why I tried pyrex, a python-like programming language that lets you mix python and C data types and the compiles it into a C extension for python. The pyrex homepage says nothing about perfomance improvements, because the main purpose of pyrex is developing python module wrapping C libraries in a easy way. It's more o less the same thing that SWIG does. But besides this, I wanted to try it.
My Fitness function
The implemetation in pure python of my fitness function can be viewed below. The function is simple, it receives two lists and try to count the times a given position of the list indiv has exactly the same value in the traffic list. If this is true, a weight value is added to count. The weight allow me to favour some position than others.
def compara(indiv,traffic):
wfeat=[0.1,0.1,0.1,0.1,0.5,0.1,0.4,0.4,0.2,0.3,0.7,0.7,0.7,0.7,0.1]
count=0
for instance in traffic:
for feature in xrange(0,len(indiv)):
if indiv[feature] >= 0:
if indiv[feature] == instance[feature]:
count+=(1 * wfeat[feature])
else:
count+=(0.25 * wfeat[feature])
else:
count+=(1 * wfeat[feature])
return count
This simple function is very time consuming because it's invoqued more than 30000 times. So my idea was to implement this function y pyrex and see what happens.
The implementation in pyrex was very easy, is basically python with types. I have to put some array limits like in the wfeat, and the function also has hardcode the bondary check to 14. Note the non-pythonic for implementation, this is the way pyrex recomends to use for. Here is my compara.pyx
def compara (indiv,instance):
cdef int feature
cdef float wfeat[14]
cdef float count
wfeat[0]=0.1
wfeat[1]=0.1
wfeat[2]=0.1
wfeat[3]=0.1
wfeat[4]=0.5
wfeat[5]=0.1
wfeat[6]=0.4
wfeat[7]=0.4
wfeat[8]=0.2
wfeat[9]=0.3
wfeat[10]=0.7
wfeat[11]=0.7
wfeat[12]=0.7
wfeat[13]=0.7
count=0.0
for feature from 0 <= feature < 14:
if indiv[feature] >= 0:
if indiv[feature] == instance[feature]:
count=count+(1 * wfeat[feature])
else:
count=count+(0.25 * wfeat[feature])
else:
count=count+(1 * wfeat[feature])
return count
The next thing I do is to use the pyrex tool to build a C file ready to be built as a python module. I simply do:
pyrex compara.pyx
gcc -c -fPIC -I/usr/include/python2.4/ compara.c
After that I got a compara.so dynamic python module ready to be imported into my application. Yupppie! After that I tested the new pyrex module and for my surprise the result was not the one I expected, the overall time of the application had barelly changed :(. I was very dissapointed. Googling a bit looking for an answer for this bad result I found this [IBM article] that explain my problem. Basically pyrex speedups python programs with a significant amount of numeric calculation. But if a program spend more of its time doing libraries call is just not going to be benefited by pyrex. In order to speed up the code you need to avoid the use of the most native python types as you can. In my case indiv and instance are still python natives types and changing that is not a trivial task.
I have been using the [psyco] JIT compiler with excelente results and with a minimun source code modification needed, but psyco faces the problem of being only supported for IA32 systems and I have a few AMD64 machines that I would like to use... I was hoping pyrex saved me of this problem but this was not the case.
Sun Jun 3 20:33:26 ART 2007
Fun with dwm
For the last three years I was using wmi as my window manager. wmi is a simple and very basic window manager. But with a few cool features. Strong key bindings (everything could be done with the keyboard). A window tiled mode, which is very usefull to me, because i use to lost my xterm behind all my others windows. A simple status bar, with a very cool feature. You can put everything you want in the status bar via the wmiremote command. So with a simple script like the one below you can have a clock, a battery monitor , information about the song you are playing a so on.
while true
do
unset infostr
hora="[`date +%d/%m" "%H:%M`hs]"
power="[`apm|awk '{print $5,$1}'|tr -d ,`]"
bat="`cat /proc/apm|awk '{print $7}'`"
signal="[`cat /proc/net/wireless |grep wlan0|awk '{print $3}'`Db]"
playing="`mpc|head -n 1|grep -v "vol"` "
playing_percent=(`mpc|egrep "\[playing.*%"`)
test -n "$playing" && infostr+=$playing
test -n "$playing_percent" && infostr+=${playing_percent[2]}\
${playing_percent[3]}
test -n "$temp" && infostr+=$temp
test -n "$signal" && infostr+=$signal
infostr+=$hora
infostr+=$power
test -n "$centericq" && infostr+=$centericq
wmiremote -t "$infostr"
sleep 30
done
But now this is over for me, why? because a found a new window manager, made by the same people who made wmi, Anselm Garbe and others. dwm is the name of this new window manager. The main idea of dwm is to write a window manager in less of 3000 lines of code :).But despite this, dwm has also very cool features. The first one is the the tiled windows autoarragment. That is, you have a window layout predefined. A master windows using most of your screen and if you have more than one window open in your screen these goes to a second smaller area on the left of your screen called stacked area. If you have to open a new aplication, this one goes to the master area and the previous application moves to the stacked area. This is called Zoom.
Its very small size and the fact that is written in C, give me the oportunity
to learn how to implement a window manager. Beside this, dwm has all the nice
features wmi also have, but because is so small, even me can add a feature or
two without a problem. And I actually did it 
But this goes in another post!
