• Publicidad

Optimizar script

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Optimizar script

Notapor Stoner » 2011-03-31 09:43 @446

Hola perleros.
Tengo un problema de optimización con un pequeño script. Lo que tengo que hacer es: teniendo dos archivos, comprobar que la primera parte (hasta el primer espacio) de cada línea de uno de los archivos se encuentre en el otro archivo, y de no ser así, pegar toda esa línea en un nuevo archivo resultado.

Mi script es el siguiente;

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4.  
  5. use warnings;
  6.  
  7. open (FILE ,"archivo1");
  8. open (FILE2 ,"archivo2");
  9.  
  10. my %hash;
  11.  
  12. foreach my $line (<FILE>)
  13. {
  14.         my @linea = split( /\t/, $line );
  15.         my $lectura = $linea[0];
  16.         my $veces++;
  17.         $hash{$lectura} = $veces;
  18. }
  19. foreach my $line2 (<FILE2>)
  20. {
  21.         my @linea2 = split( /\t/, $line2 );
  22.         my $lectura2 = $linea2[0];
  23.         unless (defined $hash{$lectura2})
  24.                 {
  25.                 open OUTPUT,">>resultado";
  26.                 print OUTPUT "$line2";
  27.                 close OUTPUT;
  28.                 }
  29. }
  30. close (FILE);
  31. close (FILE2);
  32.  
  33. END;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


El script hace lo que pretendo, pero el gran problema es que mis archivos son terriblemente grandes (aproximadamente unos 4GB cada uno, aunque los he particionado).

¿Alguna idea de cómo podría hacer que mi programa fuera más rápido?

Hasta el momento, de todas las soluciones que he probado la de trabajar con el hash es la que mejor resultado me ha dado (grep era mucho más lento).

Un saludo.
Stoner
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2011-03-31 08:41 @403

Publicidad

Re: Optimizar script

Notapor explorer » 2011-03-31 10:20 @472

Bienvenido a los foros de Perl en español, Stoner.

Esta puede ser una forma (no probada):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #use strict;                            # comentamos a estos dos, para desactivar los controles
  3. #use warnings;
  4.  
  5. open (OUTPUT, '>>','resultado');        # solo abrimos una vez el fichero resultado
  6.  
  7. my %hash;
  8. open FILE1 , '<', 'archivo1';
  9. while (<FILE1>) {
  10.    $hash{ (split /\t/, $_, 2)[0] } = 1; # partimos en 2 cada línea, y nos quedamos con la [0]
  11. }
  12. close FILE1;
  13.  
  14. my $linea;
  15. open FILE2 , '<', 'archivo2';
  16. while ($linea = <FILE2>) {
  17.     if ( not exists $hash{ (split /\t/, $linea, 2)[0] } ) {
  18.         print OUTPUT $linea;
  19.     }
  20. }
  21. close OUTPUT;
  22. close FILE2;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

También depende un poco de cómo sean los ficheros de entrada, se podría optimizar los split().

Si usas Perl v5.10, se puede también escribir así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ($linea = <FILE2>) {
  2.     my $clave = (split /\t/, $linea, 2)[0];
  3.     if ( not $clave ~~ %hash ) {
  4.         print OUTPUT $linea;
  5.     }
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Cambiamos los for() por while(), ya que los primeros provocarían la lectura de todo el fichero en memoria, en lugar de los segundos, que le leerían línea a línea.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Optimizar script

Notapor Stoner » 2011-03-31 11:26 @518

El script corre mucho más rápido.

¡Muchas gracias, Explorer!
Stoner
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2011-03-31 08:41 @403


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 35 invitados