Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Please consider trimming down your <code>f_wo_append</code> function:</p> <pre><code>def f_wo_append(): '''Function without append''' P = 75 numcustomers = 0 for person in popn.people: person.customer = iscust = person.utility &gt;= P numcustomers += iscust return numcustomers </code></pre> <p><strong>Edit</strong> in response to OP's comment """This made it a lot worse! The trimmed version takes 4 times more time than the version I have posted above. """</p> <p>There is no way that that could take "4 times more" (5 times?) ... here is my code, which demonstrates a significant reduction in the "without append" case, as I suggested, and also introduces a significant improvement in the "with append" case.</p> <pre><code>import random # instead of numpy import time timer_func = time.clock # better on Windows, use time.time on *x platform class Person(object): def __init__(self, util): self.utility = util self.customer = 0 class Population(object): def __init__(self, numpeople): random.seed(1) self.people = [Person(random.uniform(0, 300)) for i in xrange(numpeople)] self.cus = [] self.noncus = [] def f_w_append(popn): '''Function with append''' P = 75 cus = [] noncus = [] for per in popn.people: if per.utility &gt;= P: per.customer = 1 cus.append(per) else: per.customer = 0 noncus.append(per) popn.cus = cus # omitted from OP's code popn.noncus = noncus # omitted from OP's code return len(cus) def f_w_append2(popn): '''Function with append''' P = 75 popn.cus = [] popn.noncus = [] cusapp = popn.cus.append noncusapp = popn.noncus.append for per in popn.people: if per.utility &gt;= P: per.customer = 1 cusapp(per) else: per.customer = 0 noncusapp(per) return len(popn.cus) def f_wo_append(popn): '''Function without append''' P = 75 for per in popn.people: if per.utility &gt;= P: per.customer = 1 else: per.customer = 0 numcustomers = 0 for per in popn.people: if per.customer == 1: numcustomers += 1 return numcustomers def f_wo_append2(popn): '''Function without append''' P = 75 numcustomers = 0 for person in popn.people: person.customer = iscust = person.utility &gt;= P numcustomers += iscust return numcustomers if __name__ == "__main__": import sys popsize, which, niter = map(int, sys.argv[1:4]) pop = Population(popsize) func = (f_w_append, f_w_append2, f_wo_append, f_wo_append2)[which] t0 = timer_func() for _unused in xrange(niter): nc = func(pop) t1 = timer_func() print "popsize=%d func=%s niter=%d nc=%d seconds=%.2f" % ( popsize, func.__name__, niter, nc, t1 - t0) </code></pre> <p>and here are the results of running it (Python 2.7.1, Windows 7 Pro, "Intel Core i3 CPU 540 @ 3.07 GHz"):</p> <pre><code>C:\junk&gt;\python27\python ncust.py 300 0 80000 popsize=300 func=f_w_append niter=80000 nc=218 seconds=5.48 C:\junk&gt;\python27\python ncust.py 300 1 80000 popsize=300 func=f_w_append2 niter=80000 nc=218 seconds=4.62 C:\junk&gt;\python27\python ncust.py 300 2 80000 popsize=300 func=f_wo_append niter=80000 nc=218 seconds=5.55 C:\junk&gt;\python27\python ncust.py 300 3 80000 popsize=300 func=f_wo_append2 niter=80000 nc=218 seconds=4.29 </code></pre> <p><strong>Edit 3</strong> Why numpy takes longer:</p> <pre><code>&gt;&gt;&gt; import numpy &gt;&gt;&gt; utils = numpy.random.uniform(0, 300, 10) &gt;&gt;&gt; print repr(utils[0]) 42.777972538362874 &gt;&gt;&gt; type(utils[0]) &lt;type 'numpy.float64'&gt; </code></pre> <p>and here's why my f_wo_append2 function took 4 times longer:</p> <pre><code>&gt;&gt;&gt; x = utils[0] &gt;&gt;&gt; type(x) &lt;type 'numpy.float64'&gt; &gt;&gt;&gt; type(x &gt;= 75) &lt;type 'numpy.bool_'&gt; # iscust refers to a numpy.bool_ &gt;&gt;&gt; type(0 + (x &gt;= 75)) &lt;type 'numpy.int32'&gt; # numcustomers ends up referring to a numpy.int32 &gt;&gt;&gt; </code></pre> <p>The empirical evidence is that these custom types aren't so fast when used as scalars ... perhaps because they need to reset the floating-point hardware each time they are used. OK for big arrays, not for scalars.</p> <p>Are you using any other numpy functionality? If not, just use the <code>random</code> module. If you have other uses for numpy, you may wish to coerce the <code>numpy.float64</code> to <code>float</code> during the population setup.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload