Curiosidad sobre __hash__()

Francesc Alted faltet en pytables.org
Mie Feb 11 14:53:46 CET 2009


A Wednesday 11 February 2009, Chema Cortes escrigué:
> Mirando de nuevo el código, no se ve nada especial. Si el objeto no
> tiene definido un método __hash__ se usa directamente el valor del
> puntero al objeto convertido en (objeto) entero largo con signo. No
> es razón suficiente para tanta diferencia de tiempos.
>
> En los tiempos para 32bits, se nota que el último caso ha tenido un
> aumento significativo en el tiempo empleado por el sistema. Tal vez
> se haya quedado sin memoria o algo. Prueba otra vez, pero cambiando
> el orden.
>
> En cuanto a los tiempos con 64bits, parecen tiempos demasiado altos
> para N=10000, incluso para 1.000.000. De todos modos he notado que
> depende mucho del orden en que se hagan las pruebas. Por ejemplo,
> mira este curioso comportamiento:
>
> In [23]: N=1000000
>
> In [24]: %time dC=dict.fromkeys(C() for i in xrange(N))
> CPU times: user 4.18 s, sys: 0.06 s, total: 4.24 s
> Wall time: 4.30 s
>
> In [26]: %time dC=dict.fromkeys(C() for i in xrange(N))
> CPU times: user 9.74 s, sys: 0.23 s, total: 9.97 s
> Wall time: 10.09 s
>
> In [28]: %time dC=dict.fromkeys(C() for i in xrange(N))
> CPU times: user 9.93 s, sys: 0.17 s, total: 10.10 s
> Wall time: 10.24 s
>
> In [30]: del dC
>
> In [31]: %time dC=dict.fromkeys(C() for i in xrange(N))
> CPU times: user 4.23 s, sys: 0.02 s, total: 4.25 s
> Wall time: 4.29 s

Pues parece que por ahí van los tiros:

In [4]: N = 1000000

In [5]: %time dA = dict.fromkeys(A() for i in xrange(N))
CPU times: user 1.84 s, sys: 0.10 s, total: 1.94 s
Wall time: 1.97 s

In [7]: %time dB = dict.fromkeys(B() for i in xrange(N))
CPU times: user 4.10 s, sys: 0.04 s, total: 4.14 s
Wall time: 4.14 s

In [9]: %time dC = dict.fromkeys(C() for i in xrange(N))
CPU times: user 6.10 s, sys: 0.05 s, total: 6.15 s
Wall time: 6.15 s

[Inexplicable a simple vista!]

Sin embargo, borrando los diccionarios existentes y tomando la 
precaución de borrar los diccionarios previos antes de cada iteración:

In [11]: del dA, dB, dC

In [12]: %time dA = dict.fromkeys(A() for i in xrange(N))
CPU times: user 2.05 s, sys: 0.00 s, total: 2.05 s
Wall time: 2.05 s

In [14]: del dA

In [15]: %time dB = dict.fromkeys(B() for i in xrange(N))
CPU times: user 1.94 s, sys: 0.00 s, total: 1.94 s
Wall time: 1.94 s

In [17]: del dB

In [18]: %time dC = dict.fromkeys(C() for i in xrange(N))
CPU times: user 1.73 s, sys: 0.00 s, total: 1.73 s
Wall time: 1.73 s

!Vaya!  Pues es difícil de creer, pero parece que la existencia de 
diccionarios anteriores afecta a la creación de los posteriores (y no 
precisamente poco).  Sinceramente, no sé a que se puede deber ya que 
veo que el proceso ipython con los 3 diccionarios en memoria usa unos 
364 MB, y mi máquina tiene 8 GB (o sea, que se usa un ridículo 5%).

No sé, todo esto me parece, como mínimo, sospechoso (bug?).  Alguien 
tiene alguna explicación?

-- 
Francesc Alted
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes


Más información sobre la lista de distribución Python-es