En perl 5, puedes emular wc -l
usando oneliner:
perl -lnE 'END {say $.}' test.txt
Cómo implementar esta funcionalidad en Raku
Si intenta implementar esto:
raku -e 'say "test.txt".IO.open.lines.elems'
resulta ser lento y usa mucha memoria
Información para reproducir:
$ wget http://eforexcel.com/wp/wp-content/uploads/2017/07/1500000%20Sales%20Records.zip
$ unzip "1500000 Sales Records.zip"
$ mv "1500000 Sales Records.csv" part.txt
$ for i in `seq 1 10`; do cat part.txt >> test.txt ; done
$ du -sh test.txt
1.8G test.txt
$ time wc -l test.txt
15000000 test.txt
real 0m0,350s
user 0m0,143s
sys 0m0,205s
$ time perl -lnE 'END { say $. }' test.txt
15000001
real 0m1,981s
user 0m1,719s
sys 0m0,256s
$ time raku -e 'say "test.txt".IO.open.lines.elems'
15000001
real 2m51,852s
user 0m25,129s
sys 0m6,378s
# Using swap (maximum uses 2.2G swap):
# Before `raku -e ''`
$ free -m
total used free shared buff/cache available
Mem: 15009 1695 12604 107 708 12917
Swap: 7583 0 7583
# After `raku -e ''`
$ free -m
total used free shared buff/cache available
Mem: 15009 752 13923 72 332 13899
Swap: 7583 779 6804
# Swap not used
$ time raku -ne '++$ andthen END .say' test.txt
15000001
real 1m44,906s
user 2m14,165s
sys 0m0,653s
$ raku -v
This is Rakudo version 2019.11 built on MoarVM version 2019.11
implementing Perl 6.d.
wc
(que debe incluir el tamaño del archivo). Gracias.raku
), aún sería bueno tenerraku -v
salida. Además, considere agregar el resultado de la sincronización de mi sugerencia actual. Además, puedo considerar cambiar al'ascii'
decodificador más tarde este fin de semana para producir un mejor momento.-l
bandera de perl ralentiza significativamente el perl y no es útil en este caso. En mi máquina para un archivo con longitud de línea aleatoria y aproximadamente 200k líneas, la eliminación de-l
resultados en una mejora del 40%.Respuestas:
Una opción que probablemente sea bastante lenta en comparación con la que
perl
vale la pena comparar:La
l
opción de línea de comando es redundante.$
Es un estado anónimo escalar.andthen
prueba que su lhs está definida, y si es así, establece ese valor como el tema ($_
) y luego evalúa sus rhs.END
es similar aperl
'sEND
. Tenga en cuenta que vuelveNil
alandthen
pero eso no importa aquí porque estamos usando laEND
declaración de 's para su efecto secundario.Varias cosas afectarán la velocidad de este código. Algunas cosas que se me ocurren:
Sobrecarga de arranque del compilador. Ignorando cualquier módulo que se esté utilizando, el
raku
compilador Rakudo tiene una sobrecarga de inicio de aproximadamente una décima de segundo en el hardware típico en comparación con uno bastante insignificanteperl
.La noción de una "línea". En
perl
, la noción predeterminada de procesamiento de línea es leer una serie de bytes, algunos de los cuales representan un final de línea. Enraku
, la noción predeterminada de procesamiento de línea es leer una cadena UTF-8, parte de la cual representa los extremos de la línea. Por lo tanto,perl
solo incurre en la sobrecarga de lectura de un decodificador ASCII (o ASCII extendido) mientras queraku
incurre en la sobrecarga de lectura de un decodificador UTF-8.Optimizaciones del compilador.
perl
generalmente está optimizado al máximo. No me sorprendería siperl -lnE 'END {say $.}' test.txt
aprovecha algunas optimizaciones inteligentes. En contraste, el trabajo en la optimización de Rakudo todavía está en sus primeros días en términos relativos.Lo único que creo que cualquiera puede hacer sobre el primero y el último de los tres puntos que he mencionado anteriormente es esperar N años y / o contribuir a la mejora del compilador.
Habrá una forma de evitar el UTF-8-raku de forma predeterminada. Quizás algo como lo siguiente ya es factible y significativamente más rápido que el valor predeterminado de raku, al menos ignorando la sobrecarga de usar un módulo llamado
foo
:donde el módulo
foo
cambia la codificación predeterminada para E / S de archivo a ASCII o lo que sea de las codificaciones disponibles .No he comprobado que esto sea factible en el Rakudo actual, pero me sorprendería si no fuera así.
fuente