benchmarks and questions for new python programmer

Terry Reedy tjreedy at udel.edu
Mon May 17 02:11:38 EDT 2004


"stormslayer" <demarchi at duke.edu> wrote in message
news:c5f75ecc.0405161733.4bc95347 at posting.google.com...
> I've been considering a shift to python.  I currently use c++builder
> (borland) or perl.  I do computational models / statistics
> programming, and was interested in python b/c it
>
> a. has a library that connects to the R stats package
> b. has code that seems way more readable than anything else
>
> There is, however, at least for my work, a hard constraint.  Execution
> time for large data sets / lots of iterations of a model needs to be
> reasonabe.

For floating point calculations, and possibly integer, you may want to use
Numerical Python, or maybe the replacement-in-progress Numarray, or SciPy,
or PyRex, or Weave, or possibly Boost.Python -- besides the suggestion of
Psyco (which is what I personally would try first, especially for iterative
integer work).


 So, I wrote a program to test it out (appended to the
> bottom of this email).  As I said, this is my first python program.
> I'm sure it is terrible, but in many ways, you hope that the
> interpreter / compiler corrects some errors (or the langauge isn't
> that easy to use after all).
>
> Benchmarks (for the paramter settings in the file):
>
> C++builder 6.0: 3 seconds
> Perl (ActivePerl 5.6.1.638): 14 seconds
> Python (ActivePython 2.3.2 Build 232): 1 minute 13 seconds

Are you getting the same results from each, so that you know they are at
least functionally equivalent if not algorithmically equivalent?  Without
identical rngs, this would require storing a sequence of outputs from one
in a disk file for each program to use.

> Python code:
>
> #!/usr/bin/env python
> import random
>
> pop=[]      # popluation of agents; initially empty list

You might as well comment this out since init rebinds this anyway.  Ditto
for gold and standard

> N = 10000     # population size
> ep = .05    # mutation rate
> its = 100   # number of times through the main loop
> gold=0      # initial number of gold adopters; (1-gold) = silver
> adopters
> standard=0  # either 1 for gold or 2 for silver
> shifts=0    # number of regime shifts
>
> def init_all():        # init globals
>     global pop, gold, standard
>     pop = []

pop = N*[None], followed by pop[i] = x in loop might be faster.
so would be pend = pop.append followed by pend(1) and pend(2) in loop
in either case, rint = random.randint followed by rint(1,2) in loop would
definitely be so.
making pop, gold, and standard local vars instead of globals wil be faster.
then end with
return pop, gold, standard

>     gold = 0
>     for i in range(N):
>         if random.randint(1,2) == 1:
>             pop.append(1)
>             gold=gold+1

gold += 1 might be (should be?) faster here and below

>         else: pop.append(2)
>     if gold>N/2: standard=1
>     else: standard=2        # if tie, silver wins
> #    print "Initial Population of Gold Users: ", gold
> # end function init_all
>
> def one_choose():

make pop, gold, standard inputs and shifts a local
same comment about lifting attribute lookups out of loop with
rint,rdom = randon.randint, random,random

>     global pop, standard, gold, shifts
>     for i in range(its):
>         temp = random.randint(0,N-1)
>         tempval = pop[temp]
>         old_stand = standard
>         if random.random()<ep:
>             if random.random()<0.5:
>                 pop[temp]=1
>                 if tempval!=pop[temp]:
>                     gold=gold+1
>                     if gold>N/2: standard=1
>             else:
>                 pop[temp]=2
>                 if tempval!=pop[temp]:
>                     gold=gold-1
>                     if gold<N/2: standard=2
>         if standard!=old_stand: shifts=shifts+1 # check for regime
> shift after each agent chooses anew
>         else:
>             if gold>N/2:
>                 if pop[temp]!=1:
>                     pop[temp]=1
>                     gold=gold+1
>                     if gold>N/2: standard=1
>             else:
>                 if pop[temp]!=2:
>                     pop[temp]=2
>                     gold=gold-1
>                     if gold<N/2: standard=2
>         if standard!=old_stand: shifts=shifts+1 # check for regime
> shift after each agent chooses anew
> #    print "Final Population of Gold Users: ", gold
> # end function one_choose
>
> # start main loop
>
>
> for i in range(1000):
>     init_all()
>     one_choose()
> print "Number of regime shifts: ", shifts
> -- 
> http://mail.python.org/mailman/listinfo/python-list
>







More information about the Python-list mailing list