[Perl] FileHandles en Windows....
Gunnar Wolf
gwolf@campus.iztacala.unam.mx
Tue, 2 Apr 2002 13:47:27 -0600 (CST)
Hola!
> Tengo una rutina que me abre archivos NDB, que son simplemente archiv=
os
> planos haciendose pasar como tablas, que tienen una estructura as=ED:
>
> NID|KEYCARD|TIMESTAMP|EVENTCODE
> 2|114|1005228840|14
> 4|18|1005228900|14
> 5|151|1005228960|16
> 6|159|1005229020|14
> 7|151|1005229020|14
> .......
Antes de continuar, te vuelvo a sugerir echarle un ojo a la funci=F3n tie d=
e
Perl (perldoc -f tie, o si est=E1s en Windows, debe estar dentro de la
p=E1gina de ayuda de perlfunc). Esto te permite hacer algo as=ED: (tomado d=
e
esa p=E1gina)
# print out history file offsets
use NDBM_File;
tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
while (($key,$val) =3D each %HIST) {
print $key, ' =3D ', unpack('L',$val), "\n";
}
untie(%HIST);
O sea, maneja por t=ED todo el indexado, ordenado, entrada y salida... Te
refieres a lo que tienes en el archivo con un simple hash. Es muy vers=E1ti=
l
y r=E1pido - Aunque, claro, mucho m=E1s limitado que una base de datos real=
=2E
> (...)
> Esto me ha funcionando bastante bien, y en muchas ocasiones abro much=
as
> tablas NDB seguidas para ver sus datos y ya sobre eso procesarlas:
>
> my %Usuarios=3D&GETNDBFILE1("usuarios.ndb");
> my %Ordenes=3D&GETNDBFILE1("ordenes.ndb");
> my %Proveedores=3D&GETNDBFILE1("proveedores.ndb");
Si lo hicieras con tie, adem=E1s, no ocupar=EDas tanta memoria - el hash es=
t=E1
amarrado al archivo, pero el archivo completo no est=E1 en memoria. Claro,
si lo que haces es cargar el cat=E1logo muy al principio y hacer una gran
cantidad de consultas, puede serte m=E1s conveniente tenerlo completo en
memoria (no s=E9 si realmente sea as=ED, habr=EDa que ver c=F3mo funciona
internamente o hacer benchmarks).
> Aparentemente sin ningun problema esto ha funcionado, pero recienteme=
nte
> con tablas "grandes" me di cuenta que cada vez que abria una tabla seguid=
a,
> se tardaba mucho m=E1s independientemente del nombre de la variabla y/o
> archivo. Crei que era un leek de algun tipo con mis variables con la
> funci=F3n, pero como soy muy estricto con mis variables siempre uso USE
> STRICT, descartando eso inmediatamente. Hice un programita sencillo, para
> probar la velocidad... en Windows me da esto:
>
> =3D=3D>Leyendo ACCESOS1, 61521 registros en 8 segundos.
> =3D=3D>Leyendo ACCESOS2, 61521 registros en 749 segundos.
> =3D=3D>Leyendo ACCESOS3, 61521 registros en 1426 segundos.
>
> En Linux, el mismo programa con el mismo archivo NDB, me da esto:
>
> =3D=3D>Leyendo ACCESOS1, 61521 registros en 4 segundos.
> =3D=3D>Leyendo ACCESOS2, 61521 registros en 4 segundos.
> =3D=3D>Leyendo ACCESOS3, 61521 registros en 4 segundos.
>
> #Nota al margen: Mi m=E1quina Windows es una Pentium III a un 1ghz. con 2=
54 mb
> de #ram. La Linux es una Celeron a 700mhz con 192mb de ram... Otra raz=F3=
n
> para #mejorar..
>
> Usando el debugger universal: print "Hasta aqui voy...", llegue a la
> conclusi=F3n que el problema esta en la funci=F3n extactamente en la line=
a:
>
> my @FileData =3D <FileHandle>;
Yo creo que se debe a la manera en que Unix y Windows manejan la
memoria... Probablemente en Windows Perl tenga que estarle pidiendo al
kernel m=E1s y m=E1s pedazos de memoria, lo cual toma bastante tiempo (ya
conoces la afici=F3n de Windows de 'thrashear' con la memoria virtual). En
los Unixes que conozco, el manejo de memoria es mucho m=E1s limpio y
eficiente.
> (...)
> 2.- Esta bien mi proceso de abrir, lockear y cerrar el archivo???
> 3.- Estoy lockeando bien el archivo??? IndigoPerl no lo permite, por eso =
el
> if, sin embargo en una tabla peque=F1a que tiene muchos accesos, siempre =
se
> corrompe estando en Linux.
No acostumbro usar flocks, pero le=ED hoy en la ma=F1ana un art=EDculo en T=
he
Perl Journal (viene en el Sysadmin de marzo, probablemente lo encuentres
a=FAn en alg=FAn Sangrons) que habla acerca de los sem=E1foros... Si vas a =
tener
concurrencia, muchas veces un flock puede quedarse corto.
> 4.- Cuando deberia de morir el FileHandle??? No se supone que es con el
> close??
S=ED, a menos que (aprovechando que usas Perl 5.6) uses filehandles l=E9xic=
os,
que mueren al salir del bloque en que fueron definidos:
sub prueba
foreach my $file (@nombres) {
open(my $archivo, $file);
(...)
} # Ac=E1 $archivo ya sali=F3 de =E1mbito. Llama a close autom=E1ticame=
nte.
# ... Aunque es un buen h=E1bito hacerlo a mano :)
}
--=20
Gunnar Wolf - gwolf@campus.iztacala.unam.mx - (+52-55)5623-1118
PGP key 1024D/8BB527AF 2001-10-23
Fingerprint: 0C79 D2D1 2C4E 9CE4 5973 F800 D80E F35A 8BB5 27AF