[Tutor] Performance of classes
Kent Johnson
kent37 at tds.net
Sun Jun 18 15:06:37 CEST 2006
Ismael Garrido wrote:
> Hello
>
> I'm writing a program to find an appropiate combination of resistances
> to obtain a desired value of resistance. The program takes into account
> how many resistances you have available and their resistance in ohms.
>
> Since this problem (as far as I can tell) requires to generate all
> possible combinations (eliminating those that are impossible -ie:
> requires 3 resistances of type A and you only have 2-), I'm trying to
> make it run as fast as possible. So far I discovered that:
> - Calling functions that return a value (ie: just "return
> self.something") is slower than just grabbing the value from the class
Yes, there is a cost to calling a function.
> - If you've got recursions, and you call them multiple times, you better
> remember what they returned last time, otherwise it can consume a lot of
> time (or to put it another way: don't go down the same road twice :)
This is the basic idea behind dynamic programming algorithms.
> - Psyco is nice :)
> - The Python Profiler is really useful in these cases :)
>
> Now, I was reading about decorators and noticed that some classes can
> inherit from object. I thought it should make no difference in speed,
> but, just because, I tried changing my class to inherit from object. Big
> surprise, it *does* change things. I was wondering if somebody could
> explain why it does? I find it quite weird!
Inheriting from object makes your class a "new-style class" which
changes some of the details of how the class works, so it's not really
surprising that there is a performance difference.
> I have attached the code, I hope that's fine. If you have any further
> optimization suggestions I would be very glad to hear them :)
generarResist() is doing a lot more work than necessary. Because i and j
both iterate the entire list, you will generate all pairs twice. Since
Resistencia(i,j) is equivalent to Resistencia(j,i) you would be better
off having j just go through the part of the list starting from i. You
can do this by iterating over indices instead of values.
Second, Resistencia(i,j).posible is going to be the same as
Resistencia(i,j, False).posible because they use the same resistors. So
there is no need to try Resistencia(i,j, False) if
Resistencia(i,j).posible is False.
def generarResist(listaRes):
resultado = []
for i in listaRes:
for j in listaRes:
r = Resistencia(i,j)
if r.posible:
resultado.append(r)
r = Resistencia(i,j, False)
if r.posible:
resultado.append(r)
return unico(resultado)
Kent
More information about the Tutor
mailing list