[pyar] Análisis sobre charla "Python más rápido que C"

Claudio Freire klaussfreire en gmail.com
Mie Abr 30 01:27:54 ART 2014


2014-04-29 21:43 GMT-03:00 Fernando Pelliccioni <fpelliccioni en gmail.com>:
>>
>> El código tuyo tiene muchas falencias, la mayor de las cuales, es que
>> no compensa el overhead de medición. Mejor sería, en vez de
>> reimplementar timeit, usarlo (el módulo timeit).
>>
>
> Creo que te referís al código Python.
> Y sí, me lo suponía, es por eso que pedí ayuda :)
> Así que por favor, si alguien sabe como utilizar algo similar a un Stopwatch
> en Python y me quiere guiar, le agradeceré.
> ¿Cómo es el tema de timeit?

https://docs.python.org/2/library/timeit.html

Es muy fácil de usar, y compensa el overhead de medición.

>> 2014-04-29 19:34 GMT-03:00 Fernando Pelliccioni <fpelliccioni en gmail.com>:
>> >
>> > Porfa, chequeen el codigo Python y díganme si se les parece correcto,
>> > tanto
>> > el algoritmo como la forma de medición.
>> > A los que tengan experiencia en otras implementaciones de Python, (como
>> > la
>> > que menciona Claudio, CPython), por favor, me podrían dar una mano con
>> > detalles de como instalar y compilar correctamente en esas
>> > implementaciones.
>>
>>
>> CPython es la implementación de referencia de python (o sea: lo que
>> bajás de python.org)
>
>
>
> Ah mirá vos, pensé que era otra implementación. O sea que, ¿si ejecuto...
> python my_program.py
>
> con Python 2.7.5 estoy utilizando CPython?
> Si es así, entonces creo que tengo una confusión, yo creí que CPython
> transformaba el código Python a C.

Vos estabas pensando Cython. Sutil diferencia de spelling.

>> Fijate que si querés medir lo que tarda en ejecutar una multiplicación
>> C++ (no C, lo que veo ahí no es C), no podés ni compilar con -O3 ni
>> marcar las funciones como inline y las variables como const.
>
>
> En realidad no quiero medir lo que tarda una multiplicación, el objetivo de
> incluir ese test, es para demostrar que no tiene sentido. Y justamente a ese
> punto estamos llegando.
> Estoy usando C++, así puedo usar los relojes de alta resolución, en C
> tendría que escribir el código necesario para cada plataforma.
> Además, con C++ puedo obtener la misma performance que con C y además sacar
> provecho de algunas abstracciones.
> Igual no se preocupen, voy a utilizar C++ casi como en C, o mejor dicho, ala
> FORTRAN. Creo que el código va a ser bastante entendible.

inline es una extensión de C++, y una que hace mucha diferencia.

> ¿No puedo compilar con -O3 ni usar const ni inline?

No, eso desvirtúa el benchmark. Si querés usar código optimizado,
necesitás código que haga algo (sino el compilador va a optimizar al
punto de convertirlo en un printf("3"), cosa que es completamente no
representativa).

> Entonces, muchachos, estoy comparando algo real (Python) contra algo
> imaginario (C o C++).
> Sino me prohíben marcar las funciones como "inline" o las variables "const",
> entonces, no estoy programando en C++.
> En los programas reales, en producción, solemos compilarlos usando -Ox, y
> aquí es donde salta otro punto por el cual este test es incorrecto.

Estás comparando problemas de juguete. Si querés usar todas las
capacidades de ambos lenguajes, usá un problema real. Si no, tenés que
evitar que las diferencias de los lenguajes resulten en una
comparación ilegítima. Es un problema muy común en benchmarks.

La charla mencionada en el OP usaba programas suficientemente
complejos como para no exponerse a esta singularidad del compilador de
C.


>> Porque si
>> lo hacés, el compilador va a ejecutar la multiplicación en tiempo de
>> compilación, y lo que vas a medir es lo que tarda en imprimir un
>> string prefabricado (que imagino no es la idea).
>
>
> De hecho, no va a haber siquiera string prefabricado, la función completa a
> ser removida por el compilador :)
> En Python debería ocurrir lo mismo (supongo). ¿Lo hace? Bueno, aquí tenemos
> otro punto a discutir (lo dejamos para después)

No, CPython no hace nada de eso, pero PyPy sí. Podrías probar PyPy.

> Justamente mi objetivo haciendo esta prueba era dejar en claro por qué
> considero que este test es incorrecto.

Tu ejemplo es incorrecto.

El de la charla no tiene ese problema.

> El próximo paso es modificar el test, para poder medir cuanto tarda una
> multiplicación en C o C++ usando -O3, inline, const (o sea, usando C++) pero
> evitando que el compilador remueva todo el código.
> Es fácil, ¿Se les ocurre como hacerlo?
> Luego seguimos analizando los otros test de la charla

Usá números aleatorios generados por un mersenne twister en ambos (el
random() de python es un mersenne twister).

Eso va a ser suficientemente complejo como para que gcc no lo pueda
trivializar, que es lo que querés evitar. En un programa real, la
operación no debería ser trivializable, el que sea la misma operación
al benchmark no le afecta (multiplicar 3 por 8 cuesta lo mismo que 4
por 7), pero tenés que evitar que el compilador se haga el vivo.

Lo complejo va a ser excluir el costo del MT en las mediciones.

Adelantándome, no me extrañaría que CPython sea algo así como 1000
veces más lento en eso, y PyPy capaz que igual de rápido (más o
menos).


More information about the pyar mailing list