[pyar] xrange (2.7) vs range(3.2)
Germán L. Osella Massa
gosella en gmail.com
Jue Mayo 29 15:53:05 ART 2014
Interesante... ahora, ¿por qué pasa eso?
Analizando el código en Python, se ve que ambas versiones generan el mismo
bytecode:
$ python2
Python 2.7.6 (default, Feb 26 2014, 12:01:28)
[GCC 4.8.2 20140206 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def func():
... for i in xrange(1000000):
... pass
...
>>> import dis
>>> dis.dis(func)
2 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (xrange)
6 LOAD_CONST 1 (1000000)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
3 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
>>>
$ python
Python 3.4.1 (default, May 19 2014, 17:40:19)
[GCC 4.9.0 20140507 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def func():
... for i in range(1000000):
... pass
...
>>> import dis
>>> dis.dis(func)
2 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (1000000)
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
3 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
>>>
El bytecode en ambas versiones el mismo...
Ahora, recuerdo que en Python 2.x, los enteros "pequeños" (menores a 2**31)
se representan como int mientras que los mayor a ese límite se representan
como long. En Python 3.x, ambos tipos se unificaron como el nuevo int, y
eso puede afectar los tiempos.
Viendo Objects/rangeobject.c en la rama de Python 2.7.6, uno se encuentra
que xrange usa un int para definir los rangos (por eso xrange(2**31) falla).
En cambio, en Objects/rangeobject.c de la rama de Python 3.4.1, en nuevo
range (que antes era xrange) trabaja con el nuevo int (que antes era long).
Comparando PyInt_FromLong de Objects/intobject.c de Python 2.7.6 (que es lo
que usa xrange) con PyLong_FromLong de Objects/longobject.c de Python 3.4.1
(que es lo que usan range) se puede ver que el segundo es mucho más
complejo que el primero y eso puede suma a la diferencia.
En mi netbook (con Python 2.7.6 y 3.4.1):
$ python2 -m timeit 'for i in xrange(1000000): pass'
10 loops, best of 3: 137 msec per loop
$ python -m timeit 'for i in range(1000000): pass'
10 loops, best of 3: 330 msec per loop
Ahora, ¿es culpa de range/xrange con los long/int o de la iteración en sí?
A ver...
$ python2 -m timeit -s 'lista = range(1000000)' 'for i in lista: pass'
10 loops, best of 3: 92.4 msec per loop
$ python -m timeit -s 'lista = list(range(1000000))' 'for i in lista: pass'
10 loops, best of 3: 112 msec per loop
La cosa mejora un poco pero puede verse que aún hay una diferencia entre
Python 2 y Python 3...
Habrá que ver que si hay alguna diferencia en las implementaciones de los
iteradores sobre listas o si se trata de algún cambio a nivel de la
interpretación de los bytecodes que causa la diferencia. Pero
lamentablemente ahora no puedo seguir viendo...
Sin embargo, antes de cerrar el mail, les comparto esto:
$ pypy -m timeit 'for i in xrange(1000000): pass'
100 loops, best of 3: 6.22 msec per loop
;-)
2014-05-29 8:47 GMT-03:00 Daniel <dmlistapython en gmail.com>:
>
> Hice la siguiente prueba:
>
> $ python -m timeit 'for i in xrange(1000000):' ' pass'
> 100 loops, best of 3: 18.4 msec per loop
>
> $ python3 -m timeit 'for i in range(1000000):' ' pass'
> 10 loops, best of 3: 31.3 msec per loop
>
> Por qué es más lento en python3 ¿no se supone que deberían comportase
> igual o estoy testeando mal?
>
>
>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20140529/3681858f/attachment.html>
More information about the pyar
mailing list