Discussion:
Velocidad en Python y .Net sobre Windows Mobile
(too old to reply)
Juan Pedro Fisanotti
2009-08-11 20:42:34 UTC
Permalink
Gente, para quien le interese, con fines de aprender y probar, porté una
aplicación que tenía realizada en .Net para Windows Mobile, a Python para
Windows Mobile.Se trata de un buscador de archivos en el cual trabajé
bastante para optimizar el rendimiento, ya que por ejemplo en mi Pocket Pc,
tengo 4 GB de archivos, y cuando busco por lo general necesito resultados
bien rápido...
El método fue de "caja negra", programando desde 0 la aplicación nueva, y no
copiando el código e intentando traducirlo a Python.

Seguramente la versión en Python no está programada de la mejor manera,
porque aún estoy en mis inicios con él, así que si alguno tiene ideas para
aportar, soy todo oídos :D
Y son libres de usar los fuentes para lo que prefieran.

Lo que más me sorprendió es que siendo que Python es interpretado, y que
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.


Para quien lo quiera utilizar, datos de las herramientas usadas:

Máquina virtual de Python: PyCE 2.5 (Python para Windows Mobile / Windows
CE) [1]
API para GUI: PocketPyGUI 0.7 [2]

Adjunté los archivos fuentes, pero no se si eso se puede hacer en una lista
de correos. Si no se puede, cuál es la manera común de hacerlo?
Disculpen mi noobismo :P

Saludos!

[1] http://pythonce.sourceforge.net/Wikka/HomePage
[2] http://ppygui.sourceforge.net/
--
fisa - Juan Pedro Fisanotti
Roberto Alsina
2009-08-11 20:57:37 UTC
Permalink
Post by Juan Pedro Fisanotti
Seguramente la versión en Python no está programada de la mejor manera,
porque aún estoy en mis inicios con él, así que si alguno tiene ideas para
aportar, soy todo oídos :D
Algunos comentarios de estilo en busqueda.py (no me puse a ver qué hace el
código ;-):

Me gusta más

"if subcarpetas" que "if len(subcarpetas) > 0"

Llamar a __init__() a mano desde la misma clase es un poco "feíto". Te diría
que lo refactorizes (la parte que necesitás) a un metodo "init()" y lo llames
desde __init__.

Buscador.resultado no tiene porqué ser miembro de la clase, podría ser local a
buscarInterno y devolverse como resultado de la misma, lo que haría que (por
ejemplo) la clase sea usable desde más de un hilo (que probablemente no te
interese, pero es un hábito mío escribir "reentrante" si no jode mucho :-)

Si definís buscarInterno **adentro** de buscar no necesitás guardar nada de
estado en la clase misma, no?

De hecho, casi casi que esto podría ser una función y no una clase!
--
("\''/").__..-''"`-. . Roberto Alsina
`9_ 9 ) `-. ( ).`-._.`) KDE Developer (MFCH)
(_Y_.)' ._ ) `._`. " -.-' http://lateral.netmanagers.com.ar
_..`-'_..-_/ /-'_.' The 6,855th most popular site of Slovenia
(l)-'' ((i).' ((!.' according to alexa.com (27/5/2007)
Juan Pedro Fisanotti
2009-08-11 21:31:09 UTC
Permalink
Gracias por las sugerencias!
Lo del "if subcarpetas" es algo a lo que no me termino de acostumbrar, jaja.

Comento nomas el por qué de las variables de instancia que usé (y que no sea
todo una única función):
Me pasaba al menos en .Net, que por la cantidad de veces que se llamaba al
método, la aplicación perdía muchísimo tiempo alocando y desalocando objetos
nuevos de memoria. Por ello muchas de las variables son de instancia y se
"reusan" en cada llamada recursiva al método. En .Net al menos, esto mejoró
mucho el rendimiento.
Pero es verdad que el código queda mas elegante sin esas cosas.



El 11 de agosto de 2009 17:57, Roberto Alsina
Post by Roberto Alsina
Post by Juan Pedro Fisanotti
Seguramente la versión en Python no está programada de la mejor manera,
porque aún estoy en mis inicios con él, así que si alguno tiene ideas
para
Post by Juan Pedro Fisanotti
aportar, soy todo oídos :D
Algunos comentarios de estilo en busqueda.py (no me puse a ver qué hace el
Me gusta más
"if subcarpetas" que "if len(subcarpetas) > 0"
Llamar a __init__() a mano desde la misma clase es un poco "feíto". Te diría
que lo refactorizes (la parte que necesitás) a un metodo "init()" y lo llames
desde __init__.
Buscador.resultado no tiene porqué ser miembro de la clase, podría ser local a
buscarInterno y devolverse como resultado de la misma, lo que haría que (por
ejemplo) la clase sea usable desde más de un hilo (que probablemente no te
interese, pero es un hábito mío escribir "reentrante" si no jode mucho :-)
Si definís buscarInterno **adentro** de buscar no necesitás guardar nada de
estado en la clase misma, no?
De hecho, casi casi que esto podría ser una función y no una clase!
--
("\''/").__..-''"`-. . Roberto Alsina
`9_ 9 ) `-. ( ).`-._.`) KDE Developer (MFCH)
(_Y_.)' ._ ) `._`. " -.-' http://lateral.netmanagers.com.ar
_..`-'_..-_/ /-'_.' The 6,855th most popular site of Slovenia
(l)-'' ((i).' ((!.' according to alexa.com (27/5/2007)
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa - Juan Pedro Fisanotti
Gabriel Genellina
2009-08-12 22:33:20 UTC
Permalink
En Tue, 11 Aug 2009 17:42:34 -0300, Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
Lo que más me sorprendió es que siendo que Python es interpretado, y que
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.
Python es tan interpretado como Java, o como C#. Ya casi no quedan
lenguajes interpretados "puros" como el BASIC de la Commodore64 (aparte de
bash y sus parientes); ahora casi todos (Python, los lenguajes de .Net,
Ruby, Java...) compilan el fuente y generan código intermedio que a su vez
es ejecutado por una máquina virtual.
Post by Juan Pedro Fisanotti
Comento nomas el por qué de las variables de instancia que usé (y que no sea
Me pasaba al menos en .Net, que por la cantidad de veces que se llamaba al
método, la aplicación perdía muchísimo tiempo alocando y desalocando objetos
nuevos de memoria. Por ello muchas de las variables son de instancia y se
"reusan" en cada llamada recursiva al método. En .Net al menos, esto mejoró
mucho el rendimiento.
Pero en Python esto no es así. Lo que llamás variables de instancia son
sólo nombres que apuntan a objetos; esos nombres no gastan más ni menos
memoria (bueno, sí, la memoria ocupada por la string del nombre mismo...).
Una sentencia como `a=b` no crea nuevos objetos, ni saca una copia de b,
ni necesita mucha memoria: simplemente hace que a partir de ahora, el
nombre "a" apunte al mismo objeto que está apuntando el nombre "b" en ese
momento. No hay "valores" y "referencias" como en C#: sólo existen
referencias, y TODO es un objeto (incluso las funciones, los métodos,
hasta las clases mismas y sus meta-tipos son objetos también).

Una expresión como `obj.x` no se puede "pre-calcular", ni se sabe de qué
tipo es, ni siquiera se sabe si existe el atributo `x` hasta tanto no se
intenta ir a buscarlo. `obj.x` en realidad invoca una funcion:
`type(obj).__getattribute__(obj, 'x')` (bueno, no exactamente, pero la
idea es mostrar que aún algo que parece "básico" no lo es realmente)

Así que usar `self.algo` es siempre más lento que usar una variable local,
que están optimizadas para accederlas rápidamente. La
experiencia/intuición que uno trae de otros lados no sirve de mucho
(lamentablemente) al tratar de optimizar código Python.

Leer estos dos artículos viene muy bien para evitar futuros dolores de
cabeza:
http://www.effbot.org/zone/python-objects.htm
http://www.effbot.org/zone/call-by-object.htm
(uh, alguien sabe si están traducidos al castellano?)
--
Gabriel Genellina
Juan Pedro Fisanotti
2009-08-13 02:52:49 UTC
Permalink
El 12 de agosto de 2009 19:33, Gabriel Genellina
En Tue, 11 Aug 2009 17:42:34 -0300, Juan Pedro Fisanotti <
Lo que más me sorprendió es que siendo que Python es interpretado, y que
Post by Juan Pedro Fisanotti
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.
Python es tan interpretado como Java, o como C#. Ya casi no quedan
lenguajes interpretados "puros" como el BASIC de la Commodore64 (aparte de
bash y sus parientes); ahora casi todos (Python, los lenguajes de .Net,
Ruby, Java...) compilan el fuente y generan código intermedio que a su vez
es ejecutado por una máquina virtual.
Si? Yo supuse que tanto bytecode como MSIL (los lenguajes a los que compilan
java y .net) serían mucho mas cercanos a assembler, por lo que el trabajo de
interpretar dicho código es menor que al de interpretar el Python en un
archivo de texto. Además, eso daría sentido a tener un compilador, en lugar
de interpretar los fuentes como con Python. Si es así, entonces el trabajo
realizado en el intérprete de Python es otra razón más para mantenerse como
mi favorito. :D
Comento nomas el por qué de las variables de instancia que usé (y que no
Post by Juan Pedro Fisanotti
sea
Me pasaba al menos en .Net, que por la cantidad de veces que se llamaba al
método, la aplicación perdía muchísimo tiempo alocando y desalocando objetos
nuevos de memoria. Por ello muchas de las variables son de instancia y se
"reusan" en cada llamada recursiva al método. En .Net al menos, esto mejoró
mucho el rendimiento.
Pero en Python esto no es así. Lo que llamás variables de instancia son
sólo nombres que apuntan a objetos; esos nombres no gastan más ni menos
memoria (bueno, sí, la memoria ocupada por la string del nombre mismo...).
Una sentencia como `a=b` no crea nuevos objetos, ni saca una copia de b, ni
necesita mucha memoria: simplemente hace que a partir de ahora, el nombre
"a" apunte al mismo objeto que está apuntando el nombre "b" en ese momento.
No hay "valores" y "referencias" como en C#: sólo existen referencias, y
TODO es un objeto (incluso las funciones, los métodos, hasta las clases
mismas y sus meta-tipos son objetos también).
Entiendo perfectamente los conceptos de objetos, referencias, etc. Llegué a
desarrollar mi propio ORM en .Net, y recorda que en Net hacer reflection es
muy complejo (no es de tipado dinámico). No soy un pibe que sabe de Visual
Basic por hobbie, vengo del mundo Microsoft pero se pensar... jeje
Una expresión como `obj.x` no se puede "pre-calcular", ni se sabe de qué
tipo es, ni siquiera se sabe si existe el atributo `x` hasta tanto no se
`type(obj).__getattribute__(obj, 'x')` (bueno, no exactamente, pero la idea
es mostrar que aún algo que parece "básico" no lo es realmente)
Así que usar `self.algo` es siempre más lento que usar una variable local,
que están optimizadas para accederlas rápidamente. La experiencia/intuición
que uno trae de otros lados no sirve de mucho (lamentablemente) al tratar de
optimizar código Python.
El problema que yo veía no era el acceso al objeto, sino la cantidad de
objetos que se generaban en memoria. Pensa que si cada objeto era local a su
llamada al método, y la aplicación actualmente llega a llamar unas 1.000
veces al método, implica que iban a crearse 1.000 objetos en memoria para
usarse solo un par de veces cada uno.
Usando un único objeto en self, la cantidad de objetos en memoria se reduce
en 999, y eso en un móvil es mucho.

Pero como apenas estoy aprendiendo con Python, tomando tu consejo me hice un
pequeño ejemplo primero para testear como se comportaba la aplicación usando
las dos alternativas:

Código A:

class ProbadorA: def ejecutar(self):
a = 1
a = a + 1

x = ProbadorB()
for i in range(99999999):
x.ejecutar()


Resultado: 45 segudos

Código B:

class ProbadorB: def __init__(self):
self.a = 0

def ejecutar(self):
self.a = 1
self.a = self.a + 1

x = ProbadorB()
for i in range(99999999):
x.ejecutar()


Resultado: 63 segundos


Así que evidentemente, como vos me decías, es más óptimo utilizar variables
locales. Muy diferente a lo que pasaba con .Net (donde usando esta técnica
el tiempo era casi el doble que usando variables de instancia).

Llevando los cambios a la aplicación real, los tiempos mejoraron muchisimo!!
:D
Gracias por la info!!
Leer estos dos artículos viene muy bien para evitar futuros dolores de
http://www.effbot.org/zone/python-objects.htm
http://www.effbot.org/zone/call-by-object.htm
(uh, alguien sabe si están traducidos al castellano?)
(no te preocupes, entiendo bien el inglés)
--
Gabriel Genellina
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa - Juan Pedro Fisanotti
Mariano Guerra
2009-08-13 04:07:11 UTC
Permalink
Post by Juan Pedro Fisanotti
Post by Gabriel Genellina
En Tue, 11 Aug 2009 17:42:34 -0300, Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
Lo que más me sorprendió es que siendo que Python es interpretado, y que
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.
Python es tan interpretado como Java, o como C#. Ya casi no quedan
lenguajes interpretados "puros" como el BASIC de la Commodore64 (aparte de
bash y sus parientes); ahora casi todos (Python, los lenguajes de .Net,
Ruby, Java...) compilan el fuente y generan código intermedio que a su vez
es ejecutado por una máquina virtual.
Si? Yo supuse que tanto bytecode como MSIL (los lenguajes a los que compilan
java y .net) serían mucho mas cercanos a assembler, por lo que el trabajo de
interpretar dicho código es menor que al de interpretar el Python en un
archivo de texto. Además, eso daría sentido a tener un compilador, en lugar
de interpretar los fuentes como con Python. Si es así, entonces el trabajo
realizado en el intérprete de Python es otra razón más para mantenerse como
mi favorito. :D
python tiene una maquina virtual de pila como la tiene java y .NET la
unica diferencia es que python tiene que hacer muchas mas decisiones
en tiempo de ejecucion que C# y java debido a su caracter dinamico.
Asi que los 3 son igualmente interepretados :)
Post by Juan Pedro Fisanotti
El problema que yo veía no era el acceso al objeto, sino la cantidad de
objetos que se generaban en memoria. Pensa que si cada objeto era local a su
llamada al método, y la aplicación actualmente llega a llamar unas 1.000
veces al método, implica que iban a crearse 1.000 objetos en memoria para
usarse solo un par de veces cada uno.
Usando un único objeto en self, la cantidad de objetos en memoria se reduce
en 999, y eso en un móvil es mucho.
Pero como apenas estoy aprendiendo con Python, tomando tu consejo me hice un
pequeño ejemplo primero para testear como se comportaba la aplicación usando
        a = 1
        a = a + 1
x = ProbadorB()
    x.ejecutar()
Resultado: 45 segudos
        self.a = 0
        self.a = 1
        self.a = self.a + 1
x = ProbadorB()
    x.ejecutar()
Resultado: 63 segundos
Así que evidentemente, como vos me decías, es más óptimo utilizar variables
locales. Muy diferente a lo que pasaba con .Net (donde usando esta técnica
el tiempo era casi el doble que usando variables de instancia).
Llevando los cambios a la aplicación real, los tiempos mejoraron muchisimo!!
:D
Gracias por la info!!
hay mas formas de optimizar que esas y lo unico que hace mas lento uno
al otro es (hasta donde se) el lookup de a en self (el interprete
tiene que buscar en el diccionario local del objeto una variable
llamada "a" y traer el valor

aca tenes ejemplos de mas mejoras que podes hacer sobre el ejemplo que
diste (le saque unos cuantos nueves asi no me pagina a disco)

tu version:

***@ganesha ~/tmp # cat test1.py
class ProbadorA:
def ejecutar(self):
a = 1
a = a + 1

x = ProbadorA()
for i in range(9999999):
x.ejecutar()
***@ganesha ~/tmp # time python test1.py

real 0m8.391s
user 0m7.804s
sys 0m0.396s

sacandose de encima unos cuantos lookups (y usando xrange):

***@ganesha ~/tmp # cat test1.py
class ProbadorA:
def ejecutar(self):
a = 1
a += 1

x = ProbadorA().ejecutar
for i in xrange(9999999):
x()
***@ganesha ~/tmp # time python test1.py

real 0m5.309s
user 0m5.156s
sys 0m0.028s

ahora los ejemplos con self

***@ganesha ~/tmp # cat test1.py
class ProbadorA:
def __init__(self):
self.a = 0

def ejecutar(self):
self.a = 1
self.a = self.a + 1

x = ProbadorA()
for i in range(9999999):
x.ejecutar()
***@ganesha ~/tmp # time python test1.py

real 0m12.174s
user 0m11.421s
sys 0m0.300s


***@ganesha ~/tmp # cat test1.py
class ProbadorA:
def __init__(self):
self.a = 0

def ejecutar(self):
self.a = 1
self.a += 1

x = ProbadorA().ejecutar
for i in xrange(9999999):
x()
***@ganesha ~/tmp # time python test1.py

real 0m9.411s
user 0m9.001s
sys 0m0.048s

para los curiosos del bajo nivel, aca esta la salida del siguiente programa:

class ProbadorA:
def __init__(self):
self.a = 0

def ejecutar(self):
self.a = 1
self.a = self.a + 1

def ejecutar1(self):
self.a = 1
self.a += 1

def ejecutar2(self):
a = 1
a = a + 1

def ejecutar3(self):
a = 1
a += 1

import dis

print "ejecutar :"
print dis.dis(ProbadorA.ejecutar)
print "ejecutar1 :"
print dis.dis(ProbadorA.ejecutar1)
print "ejecutar2 :"
print dis.dis(ProbadorA.ejecutar2)
print "ejecutar3 :"
print dis.dis(ProbadorA.ejecutar3)

salida:

ejecutar :
6 0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)

7 9 LOAD_FAST 0 (self)
12 LOAD_ATTR 0 (a)
15 LOAD_CONST 1 (1)
18 BINARY_ADD
19 LOAD_FAST 0 (self)
22 STORE_ATTR 0 (a)
25 LOAD_CONST 0 (None)
28 RETURN_VALUE

ejecutar1 :
10 0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)

11 9 LOAD_FAST 0 (self)
12 DUP_TOP
13 LOAD_ATTR 0 (a)
16 LOAD_CONST 1 (1)
19 INPLACE_ADD
20 ROT_TWO
21 STORE_ATTR 0 (a)
24 LOAD_CONST 0 (None)
27 RETURN_VALUE

ejecutar2 :
14 0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)

15 6 LOAD_FAST 1 (a)
9 LOAD_CONST 1 (1)
12 BINARY_ADD
13 STORE_FAST 1 (a)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE

ejecutar3 :
18 0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)

19 6 LOAD_FAST 1 (a)
9 LOAD_CONST 1 (1)
12 INPLACE_ADD
13 STORE_FAST 1 (a)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE

fijate que para asignar una variable local hace:
# a = 1
0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)

para una variable de instancia hace:
# self.a = 1
0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)
Juan Pedro Fisanotti
2009-08-13 13:06:12 UTC
Permalink
Esa es otra de las cosas que me encantó de Python: la facilidad con la cual
se pueden hacer referencias a métodos (a = algo.unmetodo). En .Net se puede
hacer algo del estilo, con Delegados, pero te lleva muchas más líneas de
código y es bastante "feo".
Esto facilita mucho implementar eventos :D



El 13 de agosto de 2009 01:07, Mariano Guerra
Post by Gabriel Genellina
Post by Juan Pedro Fisanotti
Post by Gabriel Genellina
En Tue, 11 Aug 2009 17:42:34 -0300, Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
Lo que más me sorprendió es que siendo que Python es interpretado, y
que
Post by Juan Pedro Fisanotti
Post by Gabriel Genellina
Post by Juan Pedro Fisanotti
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.
Python es tan interpretado como Java, o como C#. Ya casi no quedan
lenguajes interpretados "puros" como el BASIC de la Commodore64 (aparte
de
Post by Juan Pedro Fisanotti
Post by Gabriel Genellina
bash y sus parientes); ahora casi todos (Python, los lenguajes de .Net,
Ruby, Java...) compilan el fuente y generan código intermedio que a su
vez
Post by Juan Pedro Fisanotti
Post by Gabriel Genellina
es ejecutado por una máquina virtual.
Si? Yo supuse que tanto bytecode como MSIL (los lenguajes a los que
compilan
Post by Juan Pedro Fisanotti
java y .net) serían mucho mas cercanos a assembler, por lo que el trabajo
de
Post by Juan Pedro Fisanotti
interpretar dicho código es menor que al de interpretar el Python en un
archivo de texto. Además, eso daría sentido a tener un compilador, en
lugar
Post by Juan Pedro Fisanotti
de interpretar los fuentes como con Python. Si es así, entonces el
trabajo
Post by Juan Pedro Fisanotti
realizado en el intérprete de Python es otra razón más para mantenerse
como
Post by Juan Pedro Fisanotti
mi favorito. :D
python tiene una maquina virtual de pila como la tiene java y .NET la
unica diferencia es que python tiene que hacer muchas mas decisiones
en tiempo de ejecucion que C# y java debido a su caracter dinamico.
Asi que los 3 son igualmente interepretados :)
Post by Juan Pedro Fisanotti
El problema que yo veía no era el acceso al objeto, sino la cantidad de
objetos que se generaban en memoria. Pensa que si cada objeto era local a
su
Post by Juan Pedro Fisanotti
llamada al método, y la aplicación actualmente llega a llamar unas 1.000
veces al método, implica que iban a crearse 1.000 objetos en memoria para
usarse solo un par de veces cada uno.
Usando un único objeto en self, la cantidad de objetos en memoria se
reduce
Post by Juan Pedro Fisanotti
en 999, y eso en un móvil es mucho.
Pero como apenas estoy aprendiendo con Python, tomando tu consejo me hice
un
Post by Juan Pedro Fisanotti
pequeño ejemplo primero para testear como se comportaba la aplicación
usando
Post by Juan Pedro Fisanotti
a = 1
a = a + 1
x = ProbadorB()
x.ejecutar()
Resultado: 45 segudos
self.a = 0
self.a = 1
self.a = self.a + 1
x = ProbadorB()
x.ejecutar()
Resultado: 63 segundos
Así que evidentemente, como vos me decías, es más óptimo utilizar
variables
Post by Juan Pedro Fisanotti
locales. Muy diferente a lo que pasaba con .Net (donde usando esta
técnica
Post by Juan Pedro Fisanotti
el tiempo era casi el doble que usando variables de instancia).
Llevando los cambios a la aplicación real, los tiempos mejoraron
muchisimo!!
Post by Juan Pedro Fisanotti
:D
Gracias por la info!!
hay mas formas de optimizar que esas y lo unico que hace mas lento uno
al otro es (hasta donde se) el lookup de a en self (el interprete
tiene que buscar en el diccionario local del objeto una variable
llamada "a" y traer el valor
aca tenes ejemplos de mas mejoras que podes hacer sobre el ejemplo que
diste (le saque unos cuantos nueves asi no me pagina a disco)
a = 1
a = a + 1
x = ProbadorA()
x.ejecutar()
real 0m8.391s
user 0m7.804s
sys 0m0.396s
a = 1
a += 1
x = ProbadorA().ejecutar
x()
real 0m5.309s
user 0m5.156s
sys 0m0.028s
ahora los ejemplos con self
self.a = 0
self.a = 1
self.a = self.a + 1
x = ProbadorA()
x.ejecutar()
real 0m12.174s
user 0m11.421s
sys 0m0.300s
self.a = 0
self.a = 1
self.a += 1
x = ProbadorA().ejecutar
x()
real 0m9.411s
user 0m9.001s
sys 0m0.048s
self.a = 0
self.a = 1
self.a = self.a + 1
self.a = 1
self.a += 1
a = 1
a = a + 1
a = 1
a += 1
import dis
print "ejecutar :"
print dis.dis(ProbadorA.ejecutar)
print "ejecutar1 :"
print dis.dis(ProbadorA.ejecutar1)
print "ejecutar2 :"
print dis.dis(ProbadorA.ejecutar2)
print "ejecutar3 :"
print dis.dis(ProbadorA.ejecutar3)
6 0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)
7 9 LOAD_FAST 0 (self)
12 LOAD_ATTR 0 (a)
15 LOAD_CONST 1 (1)
18 BINARY_ADD
19 LOAD_FAST 0 (self)
22 STORE_ATTR 0 (a)
25 LOAD_CONST 0 (None)
28 RETURN_VALUE
10 0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)
11 9 LOAD_FAST 0 (self)
12 DUP_TOP
13 LOAD_ATTR 0 (a)
16 LOAD_CONST 1 (1)
19 INPLACE_ADD
20 ROT_TWO
21 STORE_ATTR 0 (a)
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
14 0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)
15 6 LOAD_FAST 1 (a)
9 LOAD_CONST 1 (1)
12 BINARY_ADD
13 STORE_FAST 1 (a)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
18 0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)
19 6 LOAD_FAST 1 (a)
9 LOAD_CONST 1 (1)
12 INPLACE_ADD
13 STORE_FAST 1 (a)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
# a = 1
0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (a)
# self.a = 1
0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (a)
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa - Juan Pedro Fisanotti
Ernesto Savoretti
2009-08-13 14:08:55 UTC
Permalink
Post by Juan Pedro Fisanotti
Esa es otra de las cosas que me encantó de Python: la facilidad con la cual
se pueden hacer referencias a métodos (a = algo.unmetodo). En .Net se puede
hacer algo del estilo, con Delegados, pero te lleva muchas más líneas de
código y es bastante "feo".
Esto facilita mucho implementar eventos :D
Python está lleno de magia, y esta que vos mencionás es una de las que
para mi gusto más atrae...
Obviamente es un tributo a su naturaleza dinámica.
Lo interesante es que habitualmente la magia de Python no es negra, lo
más típico es que si querés escarbar como funciona algo lo puedas
hacer y comprender rápidamente que hay detrás de la magia, y cuando
ves que toda esa magia se construyó con simpleza y economía de
recursos, ahí aparece la sorpresa y admiración por lo que llamaría la
elegancia de Python.

PD: si seguís haciendo top-posting alguien te va a retar, así que más
temprano que tarde...este cordial recordatorio. Es un tema práctico,
como Python.
--
Ernesto Savoretti
Juan Pedro Fisanotti
2009-08-13 15:26:15 UTC
Permalink
Post by Ernesto Savoretti
Post by Juan Pedro Fisanotti
Esa es otra de las cosas que me encantó de Python: la facilidad con la
cual
Post by Juan Pedro Fisanotti
se pueden hacer referencias a métodos (a = algo.unmetodo). En .Net se
puede
Post by Juan Pedro Fisanotti
hacer algo del estilo, con Delegados, pero te lleva muchas más líneas de
código y es bastante "feo".
Esto facilita mucho implementar eventos :D
Python está lleno de magia, y esta que vos mencionás es una de las que
para mi gusto más atrae...
Obviamente es un tributo a su naturaleza dinámica.
Lo interesante es que habitualmente la magia de Python no es negra, lo
más típico es que si querés escarbar como funciona algo lo puedas
hacer y comprender rápidamente que hay detrás de la magia, y cuando
ves que toda esa magia se construyó con simpleza y economía de
recursos, ahí aparece la sorpresa y admiración por lo que llamaría la
elegancia de Python.
Tenes toda la razón.. al menos es la sensación que me está dando a mí, en
este tiempo que lo retomé. Y se potencia con el hecho de que vengo cansado
de la "sobrecarga" (y otras historias) de .Net y Java...
Post by Ernesto Savoretti
PD: si seguís haciendo top-posting alguien te va a retar, así que más
temprano que tarde...este cordial recordatorio. Es un tema práctico,
como Python.
Ok, otra netiqueta que no conocía :D
Gracias por mencionarlo
Post by Ernesto Savoretti
--
Ernesto Savoretti
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa - Juan Pedro Fisanotti
Marcelo Fernández
2009-08-13 17:28:07 UTC
Permalink
[...]
Post by Ernesto Savoretti
PD: si seguís haciendo top-posting alguien te va a retar, así que más
temprano que tarde...este cordial recordatorio. Es un tema práctico,
como Python.
Ok, otra netiqueta que no conocía :D
Gracias por mencionarlo
Podemos agregar mails en sólo texto y no HTML? :-)

Saludos y muy constructivo el hilo...
--
Marcelo F. Fernández
Buenos Aires, Argentina
Licenciado en Sistemas de Información - CCNA

E-Mail: marcelo.fidel.fernandez-***@public.gmane.org
Jabber ID: fernandezm22-/eSpBmjxGS4dnm+***@public.gmane.org
Public Key ID: 5C990A6C 111C3661
Blog: http://blog.marcelofernandez.info
Juan Pedro Fisanotti
2009-08-13 17:38:39 UTC
Permalink
El 13 de agosto de 2009 14:28, Marcelo Fernández
Post by Marcelo Fernández
[...]
   PD: si seguís haciendo top-posting alguien te va a retar, así que más
   temprano que tarde...este cordial recordatorio. Es un tema práctico,
   como Python.
Ok, otra netiqueta que no conocía :D
Gracias por mencionarlo
Podemos agregar mails en sólo texto y no HTML? :-)
Mmmm... voy a pensarlo...  jaja :D
Ok
Post by Marcelo Fernández
Saludos y muy constructivo el hilo...
--
Marcelo F. Fernández
Buenos Aires, Argentina
Licenciado en Sistemas de Información - CCNA
Public Key ID: 5C990A6C 111C3661
Blog: http://blog.marcelofernandez.info
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa  -  Juan Pedro Fisanotti
Juan Pedro Fisanotti
2009-08-14 04:17:54 UTC
Permalink
Post by Juan Pedro Fisanotti
El 13 de agosto de 2009 14:28, Marcelo Fernández
Post by Marcelo Fernández
[...]
   PD: si seguís haciendo top-posting alguien te va a retar, así que más
   temprano que tarde...este cordial recordatorio. Es un tema práctico,
   como Python.
Ok, otra netiqueta que no conocía :D
Gracias por mencionarlo
Podemos agregar mails en sólo texto y no HTML? :-)
Mmmm... voy a pensarlo...  jaja :D
Ok
Post by Marcelo Fernández
Saludos y muy constructivo el hilo...
--
Marcelo F. Fernández
Buenos Aires, Argentina
Licenciado en Sistemas de Información - CCNA
Public Key ID: 5C990A6C 111C3661
Blog: http://blog.marcelofernandez.info
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa  -  Juan Pedro Fisanotti
Bueno, luego de probar e investigar el metodo os.walk(..), me di
cuenta de la elegancia que tendría el código usándolo. Y para darle un
toque extra, miren como manejé el tema de ir reportando el progreso de
la búsqueda.. jeje.

Este es el nuevo buscador, sirve para desktop por si a alguien le interesa:


import os

class Buscador:

def buscar(self, carpeta, busqueda, on_progreso):
resultado = []
palabras = busqueda.upper().split()

pila_progreso = []
pila_progreso.append(100.0)
progreso_total = 0.0

for carpeta_actual, subcarpetas, archivos in os.walk(carpeta):
for a in archivos:
coincide = False
archivo = a.upper()
for p in palabras:
if archivo.find(p) > -1: coincide = True
if coincide: resultado.append(archivo)

progreso = pila_progreso.pop()

if subcarpetas:
progreso = progreso / len(subcarpetas)
pila_progreso.extend([progreso for i in
range(len(subcarpetas))])
else:
progreso_total += progreso
on_progreso(progreso_total)

return resultado


Escucho consejos! :D
--
fisa - Juan Pedro Fisanotti
Mariano Guerra
2009-08-14 04:33:46 UTC
Permalink
Post by Juan Pedro Fisanotti
import os
       resultado = []
       palabras = busqueda.upper().split()
       pila_progreso = []
       pila_progreso.append(100.0)
       progreso_total = 0.0
               coincide = False
               archivo = a.upper()
                   if archivo.find(p) > -1: coincide = True
               if coincide: resultado.append(archivo)
           progreso = pila_progreso.pop()
               progreso = progreso / len(subcarpetas)
               pila_progreso.extend([progreso for i in
range(len(subcarpetas))])
               progreso_total += progreso
               on_progreso(progreso_total)
       return resultado
Escucho consejos! :D
solo cuestiones de gustos, en

if archivo.find(p) > -1:

a mi me gusta mas
Post by Juan Pedro Fisanotti
"pa" in "palabra"
True
Post by Juan Pedro Fisanotti
"lab" in "palabra"
True
Post by Juan Pedro Fisanotti
"asd" in "otra cosa"
False

aca:

if archivo.find(p) > -1: coincide = True
if coincide: resultado.append(archivo)

no podrias hacer?

if p in archivo:
resultado.append(archivo)
break

de esa forma salis del for mas rapido y te sacas la variable coincide del medio

bue, me voy a dormir.

saludos
Gabriel Genellina
2009-08-14 10:25:01 UTC
Permalink
En Fri, 14 Aug 2009 01:17:54 -0300, Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
import os
No todo hay que ponerlo adentro de una clase en Python. Tambien podes
escribir funciones "sueltas"; una funcion no deja de ser un objeto por el
hecho de no estar adentro de una clase, y tu codigo no es menos "OO" por
usarla. Fijate que el "self" de Buscador no se usa para nada...
Post by Juan Pedro Fisanotti
if coincide: resultado.append(archivo)
Probablemente te convenga usar os.path.join(carpeta_actual, archivo) en
lugar de archivo a secas.
Post by Juan Pedro Fisanotti
progreso = pila_progreso.pop()
Me gustó la barra de progreso!!!

En Fri, 14 Aug 2009 01:33:46 -0300, Mariano Guerra
Post by Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
               coincide = False
               archivo = a.upper()
                   if archivo.find(p) > -1: coincide = True
               if coincide: resultado.append(archivo)
a mi me gusta mas
resultado.append(archivo)
break
de esa forma salis del for mas rapido y te sacas la variable coincide del medio
Y siguiendo la misma idea, en palabras, eso se diría "si alguna de las
`palabras` esta contenida en `archivo`, agregar `archivo` al `resultado`"

if any(p in archivo for p in palabras):
resultado.append(archivo)

Que al principio pueden parecer jeroglíficos egipcios, pero es igual a la
frase de arriba, y si la escribieramos en inglés se parece más todavia...
--
Gabriel Genellina
Juan Pedro Fisanotti
2009-08-14 12:41:57 UTC
Permalink
El 14 de agosto de 2009 07:25, Gabriel
Post by Gabriel Genellina
Post by Juan Pedro Fisanotti
import os
No todo hay que ponerlo adentro de una clase en Python. Tambien podes
escribir funciones "sueltas"; una funcion no deja de ser un objeto por el
hecho de no estar adentro de una clase, y tu codigo no es menos "OO" por
usarla. Fijate que el "self" de Buscador no se usa para nada...
La verdad que sí. Es algo a lo que me acostumbró C#, que me va a
costar dejar.. jeje..
Post by Gabriel Genellina
Post by Juan Pedro Fisanotti
               if coincide: resultado.append(archivo)
Probablemente te convenga usar os.path.join(carpeta_actual, archivo) en
lugar de archivo a secas.
En realidad voy a hacer que cada elemento del resultado tenga las dos
cosas: el nombre solo, y el path completo. Así en la aplicación puedo
mostrar el nombre solo sin tener que extraerlo, y cuando le haga click
tengo el path completo para abrir el archivo.
Post by Gabriel Genellina
Post by Juan Pedro Fisanotti
           progreso = pila_progreso.pop()
Me gustó la barra de progreso!!!
Esas cosas solo se me ocurren a la 1 de la mañana :D
Post by Gabriel Genellina
En Fri, 14 Aug 2009 01:33:46 -0300, Mariano Guerra
Post by Juan Pedro Fisanotti
Post by Juan Pedro Fisanotti
               coincide = False
               archivo = a.upper()
                   if archivo.find(p) > -1: coincide = True
               if coincide: resultado.append(archivo)
a mi me gusta mas
   resultado.append(archivo)
   break
de esa forma salis del for mas rapido y te sacas la variable coincide del medio
Y siguiendo la misma idea, en palabras, eso se diría "si alguna de las
`palabras` esta contenida en `archivo`, agregar `archivo` al `resultado`"
 resultado.append(archivo)
Que al principio pueden parecer jeroglíficos egipcios, pero es igual a la
frase de arriba, y si la escribieramos en inglés se parece más todavia...
Perfecto, ahora lo dejé como me dijeron :D


Gracias otra vez por los comentarios!! Estos proyectitos me están
ayudando a aprender mucho.
Post by Gabriel Genellina
--
Gabriel Genellina
---------------------------------------------------------------------
PyAr - Python Argentina - Sitio web: http://www.python.com.ar/
--
fisa - Juan Pedro Fisanotti
Facundo Batista
2009-08-11 23:33:33 UTC
Permalink
Post by Juan Pedro Fisanotti
Lo que más me sorprendió es que siendo que Python es interpretado, y que
además tengo pocos conocimientos en el mismo, logré la misma velocidad que
con .Net, que es precompilado y en el cual pude hilar muy fino en
optimización.
Que loco esto... ¿quizás sea que la versión de .net usa mucha memoria?
Post by Juan Pedro Fisanotti
Adjunté los archivos fuentes, pero no se si eso se puede hacer en una lista
de correos. Si no se puede, cuál es la manera común de hacerlo?
Si son chicos, no hay problema.

Slds.
--
. Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
gustavo carmona
2009-08-12 11:05:53 UTC
Permalink
Post by Facundo Batista
Post by Juan Pedro Fisanotti
Adjunté los archivos fuentes, pero no se si eso se puede hacer en una lista
de correos. Si no se puede, cuál es la manera común de hacerlo?
Si son chicos, no hay problema.
Slds.
--
.    Facundo
Busca en otros hilos que dieron sitios donde copias y pegas codigo, te
queda a color (chiche, joya, etc) tipo [0]

[0] http://pastebin.com/
--
Gustavo C
Roberto Alsina
2009-08-12 12:02:22 UTC
Permalink
Post by gustavo carmona
Post by Facundo Batista
Post by Juan Pedro Fisanotti
Adjunté los archivos fuentes, pero no se si eso se puede hacer en una
lista de correos. Si no se puede, cuál es la manera común de hacerlo?
Si son chicos, no hay problema.
Slds.
--
. Facundo
Busca en otros hilos que dieron sitios donde copias y pegas codigo, te
queda a color (chiche, joya, etc) tipo [0]
[0] http://pastebin.com/
Nota al margen: en KDE hay un plasmoid que le pegás el texto (o una imagen) y
te lo pone automáticamente en un pastebin y te copia la URL. Es muuuuuy
práctico, capaz que para windows también hay algo así.
--
("\''/").__..-''"`-. . Roberto Alsina
`9_ 9 ) `-. ( ).`-._.`) KDE Developer (MFCH)
(_Y_.)' ._ ) `._`. " -.-' http://lateral.netmanagers.com.ar
_..`-'_..-_/ /-'_.' The 6,855th most popular site of Slovenia
(l)-'' ((i).' ((!.' according to alexa.com (27/5/2007)
Continue reading on narkive:
Loading...