[bcn-pm] Split: Perl vs. Python (vs. Awk?)

Salvador Fandiño sfandinoayahoo.com
Dis Mar 11 16:47:40 PST 2006



--- Enrique Nell <perl_nell en telefonica.net> wrote:

> Hola mongers
> 
> En la pasada edici�n de YAPC (en Braga), un Perl monger de Lisboa
> llamado
> Miguel Duarte present� una Lightning Talk titulada "Perl is slow
> for
> processing delimited records and what I've done to improve it".
> M�s tarde me pas� el c�digo que hab�a utilizado para llegar
a sus
> conclusiones y me coment� que le extra�aba que 
> los JAPH no hubieran respondido a la provocaci�n.
> Este "kit de pruebas", que os env�o adjunto, contiene un programa
> (denominado generate.pl) que genera un fichero de valores
num�ricos
> aleatorios separados por ":", versiones en Perl, Python y Awk de un
> programa
> para contar el n�mero 
> de campos, y otro programa (denominado run_benchmark.pl) que mide
> los
> tiempos de ejecuci�n de las versiones anteriores.
> En la presentaci�n, Miguel afirm� que la versi�n Java
tambi�n
> tardaba menos
> en ejecutarse que la versi�n Perl. 
> Qued� en copiar el c�digo Java en la p�gina de YAPC::2005,
pero a�n
> no lo ha
> hecho (creo que necesitaba permiso de su
> empresa para hacerlo).
>  
> Hace unos d�as vi en perl.com que los perl mongers de Lisboa iban
a
> celebrar
> una reuni�n el martes pasado y que Miguel volv�a a la carga con
> otra
> presentaci�n titulada "When not to choose Perl". Otros mongers
del
> grupo
> amenazaron con 
> recurrir a la violencia f�sica para hacerle entrar en raz�n,
pero
> no creo
> que hayan tenido �xito. Aunque sea monger y 
> la cr�tica sea constructiva, creo que ha sido abducido por el
mundo
> Java:-)
> De todos modos, eso me hizo recordar la charla de Braga, as� que
> "desempolv�" el c�digo que me pas� y me puse a hacer pruebas
en la
> siguiente
> plataforma:
>  
> Pentium Centrino a 1,3 GHz, 512 MB de RAM
> Mandrake Linux 10.1 con Perl 5.8.5, Python 2.3.4, GNU Awk 3.1.3
> Windows XP con Perl 5.8.7, Python 2.4.2, GNU Awk 3.0.4   
>  
> Los resultados:
> En Windows XP: Perl - 80 seg., Python - 16 seg., GNU Awk - 10 seg.
> En Linux:      Perl - 46 seg., Python - 18 seg., GNU Awk -  3 seg.
>  
> Conclusiones
> ============
> Diferencias entre sistemas operativos:
> - La ejecuci�n del programa Awk en Windows XP tarda m�s del
doble
> que en
> Linux.
> - La ejecuci�n del programa Perl en Windows XP tarda casi el
doble
> que en
> Linux.
> - La ejecuci�n del programa Python en Windows XP es un poco m�s
> r�pida que
> en Linux 
> (pero hay que tener en cuenta que la versi�n de Python que tengo
> instalada
> en Windows es m�s reciente).
> - Deber�a dejar de utilizar Windows (o empezar a utilizar Python
en
> Windows):-)
> 
> Diferencias entre lenguajes:
> Sobre la velocidad de Awk: igual me equivoco (porque nunca he
> programado en
> Awk), pero creo que el programa Awk no almacena los campos
> (simplemente
> cuenta el n�mero de campos), con lo cual no es equivalente a los
> programas
> Perl y Python, que s� los almacenan. En Perl se puede conseguir
el
> mismo
> resultado con estas l�neas (que tardan pr�cticamente lo mismo
que
> el
> programa Awk):
>  
> $field_count += (($_ =~ tr/:/:/) + 1) while (<>);
> 
> print "$field_count\n";
> 
> As� que descartamos Awk y no nos creemos lo de Java de momento,
> pero nos
> queda el dato inquietante: 
> la funci�n split de Python es mucho m�s r�pida que la de
Perl.
> 
> Xavier Noria y Miguel estuvieron cacharreando un rato, y llegaron a
> la
> conclusi�n de que la diferencia se deb�a a que 
> la funci�n split de Python utiliza como argumento separador de
> campos una
> cadena en lugar de una expresi�n regular.
> 
> Si los campos fueran de ancho fijo, podr�amos intentar utilizar
> unpack para
> obtener mejores resultados, pero no es 
> el caso.
>  
> Mi pregunta es: �se os ocurre alguna forma de mejorar el
> rendimiento de Perl
> en esta tarea? (se supone que adem�s de contar el n�mero de
campos,
> hay que
> almacenar los campos en una estructura de datos).

hola Enrique,

recuerdo que yo tambien estube haciendo algunas mis pruebas sobre
porque split era tan lento y la conclusion a la que llegue es que la
lentitud no era causada por usar una expresion regular o una cadena,
sino por el manejo de memoria de Perl. Si no me equivoco durante el
split se crea un SV por cada campo y al asignarlos a un array, se
duplican (osea, mas SVs) a la vez que se liberan los viejos y ademas
se liberan los valores temporales devueltos por split.

En python en cambio, se devuelve una referencia al array con los
valores, ademas como las cadenas en python son inmutables, es posible
que los objetos devueltos no se hayan creado completamente de nuevo,
si no que simplemente sean punteros a subcadenas de la cadena
original... a parte de que el manejo de memoria de Python es 
diferente y puede tener un mejor rendimiento para este caso.

Para conseguir un mejor rendimiento en Perl, lo primero seria
devolver una referencia a un array en vez de devolver los resultados
como una lista, luego tambien, en vez de devolver SVs completamente
nuevos, se podrian devolver punteros dentro de la cadena original...
desde XS, claro, y usando "magic", pero eso tambien implica crear SVs
nuevos, con lo cual habria que ver con detalle si compensa o no...
posiblemente solo lo haga si las subcadenas son muy grandes.

Saludos,

  - Salva

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Més informació de la llista de correu Barcelona-pm