ManuelPerl escribiste:¿Yo puedo comunicar un programa C por medio de tuberías con Perl?
Sí. Un ejemplo:
cat /etc/passwd | perl -nE '/root/ and print'o así:
perl -E 'open PWD, "-|", "cat /etc/passwd"; /root/ and print while <PWD>'ManuelPerl escribiste:¿Esta comunicación sería igual de rápida que si se utilizara Inline::C?
Sí y no.
Si el proceso C está siempre funcionando, y es el programa Perl el que se arranca de vez en cuando para consultarle, entonces sí. En los demás casos no (arrancar un proceso nuevo es muy costoso a nivel de recursos de una máquina).
En cambio, si se hace por medio de Inline::C, el código Perl carga esa parte como una biblioteca compilada. Hay un pequeño retraso, pero no tanto como arrancar un programa entero (bueno, depende de lo que haga el código que está en Inline::C, desde luego).
ManuelPerl escribiste:Se puede utilizar las tuberías con C para aumentar la velocidad de proceso de Perl, es decir, que C calcule y los resultados los pase por una tubería a Perl.
Claro. Ejemplo: contar el número de palabras distintas que hay al principio de cada línea de una archivo.
Using bash Syntax Highlighting
# archivo de ejemplo
$ ll lrneoris.sql
-rw------- 1 root root
1561116504 may
31 13:
32 lrneoris.sql
$
$
# en Perl, intento 1
$
time perl -E 'open PWD, "lrneoris.sql"; while (<PWD>) { @F=split; $h{$F[0]}++ } say scalar keys %h'
581
real 0m21.120s
user 0m10.457s
sys 0m0.688s
$
$
# en Perl, intento 2
$
time perl -a -n -E '$h{$F[0]}++; END { say scalar keys %h }' lrneoris.sql
581
real 0m20.803s
user 0m10.477s
sys 0m0.588s
$
$
# en C
$
time cut -d' ' -f 1 lrneoris.sql
|sort|uniq|wc -l
13
real 0m14.948s
user 0m4.244s
sys 0m0.420s
$
$
# en Perl usando C, intento 1
$
time cut -d' ' -f 1 lrneoris.sql
| perl -n -E '$h{$_}++; END { say scalar keys %h }'
13
real 0m14.185s
user 0m4.156s
sys 0m0.408s
$
$
# en Perl usando C, intento 2
$
time perl -E 'open FH, q(cut -d" " -f 1 lrneoris.sql |); $h{$_}++ while <FH>; say scalar keys %h '
13
real 0m14.701s
user 0m4.064s
sys 0m0.496s
Coloreado en 0.004 segundos, usando
GeSHi 1.0.8.4
ManuelPerl escribiste:Yo tengo un programa en C que escribe en un fichero.txt y luego Perl lee ese fichero txt. Las tuberías serían más o menos así, ¿no? ¿O más rápidas si se utiliza un archivo txt de puente entre las dos aplicaciones?
Son mucho más rápidas, ya que la información queda en la memoria del ordenador. Un archivo necesita escribirse a un sistema de archivos, y eso puede ser muy lento.
Using bash Syntax Highlighting
$
# usando un archivo
$
time { cut -d' ' -f 1 lrneoris.sql
> lineas.txt;
perl -n -E '$h{$_}++; END { say scalar keys %h }' lineas.txt;
}
13
real 0m14.625s
user 0m4.060s
sys 0m0.476s
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Una forma de acelerar este método es usando un disco RAM.
Using bash Syntax Highlighting
$
# usando un disco RAM
$
time { cut -d' ' -f 1 lrneoris.sql
> /dev
/shm
/lineas.txt;
perl -n -E '$h{$_}++; END { say scalar keys %h }' /dev
/shm
/lineas.txt;
}
13
real 0m14.511s
user 0m4.116s
sys 0m0.424s
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
(bueno, las diferencias son mínimas, porque... Perl es muy rápido
)
ManuelPerl escribiste:Era para aclararme un poco con este tema de las tuberías, porque me parecen más sencillas que aprender algunos módulos.
No sé yo...
ManuelPerl escribiste:Entonces con las tuberías yo puedo comunicar a Perl con cualquier aplicación, de otro lenguaje, del sistema operativo, es decir, con cualquier cosa, ¿estoy en lo cierto?
Las tuberías es una característica del sistema operativo. Cualquier programa puede conectarse con cualquier otro, siempre y cuando se pongan de acuerdo en lo que se van a intercambiar (no tiene sentido mandar un JPEG cuando estoy esperando un archivo de texto).
ManuelPerl escribiste:Lo único que el otro lenguaje tendría que abrir las tuberías en su lenguaje y Perl en el suyo. ¿Estoy en lo cierto o estoy equivocado?
Cada lenguaje tiene su forma de crear tuberías. En los ejemplos que te he mostrado, he usado tuberías por medio del shell, que es la forma más sencilla.
En Perl, con open, es tan sencillo como usar el '|' junto con el comando que quieres entubar. Otro tema es si ese proceso ya está arrancado... en ese caso, puedes usar
Named Pipes (ver perlipc), o memoria compartida usando el método SysV (ver módulo
IPC::SysV).
Todo esto está comentado en
perlipc, donde comenta varios métodos de interconexión y de intercambio de información, entre procesos.
Más información en tu propio ordenador en
perldoc perlipc,
y en la Web.