Página 2 de 2

Re: Mejorar script para que sea más rápido

NotaPublicado: 2015-08-06 20:18 @888
por explorer
6 horas sigue siendo demasiado... para Perl :D

Modificando la estructura una vez más, añadiendo ordenación numérica a los finales, creamos un engendro como este:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
(
  undef,
  [
    [30, [[600, "AT1G010X2"]]],
    [
      50,
      [
        [600, "AT1G010X3"],
        [500, "AT1G01021"],
        [350, "AT1G01020"],
        [300, "AT1G010X0"],
        [290, "AT1G010X1"],
      ],
    ],
    [200, [[360, "AT1G010X4"]]],
  ],
  [
    [50, [[400, "AT1G010X7"]]],
    [100, [[200, "AT1G010X6"]]],
    [200, [[300, "AT1G010X5"]]],
  ],
  [[200, [[400, "AT1G010X8"], [100, "AT1G010X9"]]]],
)
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
que es un array de arrays de arrays de arrays.

En la primera dimensión están los valores de Chr. En la segunda, los inicios asociados a ellos. En la tercera, los finales asociadas cada inicio, y en la cuarta, un array que almacena cada valor de final con el valor del gen.

Pero... con el añadido de que los finales están ordenados numéricamente, al revés, por lo que será fácil terminar el bucle si sabemos que $posicion no va a estar en el resto de finales.

Entonces el programa queda así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use feature 'say';
  3. use autodie;
  4.  
  5. #my $dir    = '/home/damian/Escritorio/Arrays/';
  6. my $dir         = '.';
  7. my $input1      = "$dir/archivo1.txt";
  8. my $input2      = "$dir/archivo2.txt";
  9. my $output      = "$dir/salida.txt";
  10.  
  11. # Procesar el segundo archivo para crear la estructura
  12. my @matrix;
  13.  
  14. open my $INPUT2, '<', $input2;
  15.  
  16. while (<$INPUT2>) {
  17.     ##    AT1G01020  1            50      350
  18.     my($gen,$chr,$inicio,$final) = split;
  19.    
  20.     $matrix[$chr]{$inicio}{$final} = $gen;
  21. }
  22.  
  23. close $INPUT2;
  24.  
  25. #use Data::Dump;
  26. #dd(@matrix);
  27.  
  28. # Ordenación de los valores de inicio, y de final
  29. for my $chr ( 1 .. $#matrix ) {
  30.     my $HoH = $matrix[$chr];
  31.  
  32.     my @inicios =                                               # ordenación de los inicios
  33.         sort { $a->[0] <=> $b->[0] }
  34.         map { [ $_, $HoH->{$_} ] }
  35.         keys %{ $HoH }
  36.         ;
  37.  
  38.     for my $inicios_ref (@inicios) {                            # para cada inicio
  39.         my $h = $inicios_ref->[1];
  40.  
  41.         my @finales =                                           # ordenamos sus finales, al revés
  42.             sort { $b->[0] <=> $a->[0] }
  43.             map { [ $_, $h->{$_} ] }
  44.             keys %{ $h }
  45.             ;
  46.  
  47.         $inicios_ref->[1] = \@finales;                          # pasamos de hash de hash a array de array
  48.     }
  49.  
  50.     $matrix[$chr] = \@inicios;                                  # para cada $chr
  51. }
  52.  
  53. #dd( @matrix );
  54.  
  55. # Procesar el primer archivo, por líneas
  56. open my $INPUT1, '<', $input1;
  57. open my $SALIDA, '>', $output;
  58.  
  59. while (<$INPUT1>) {
  60.     chomp;
  61.    
  62.     my($chr, $posicion, $cuentas) = split;
  63.    
  64.     for my $inicio_ref ( @{ $matrix[$chr] } ) {                 # recorremos todos los valores de inicio
  65.         my($inicio,$finales_ref) = @{ $inicio_ref };
  66.        
  67.         last if $inicio > $posicion;                            # salimos si $posicion ya no está dentro
  68.  
  69.         for my $final_ref ( @{ $finales_ref } ) {               # recorremos los finales asociados a ese $inicio
  70.  
  71.             last if $posicion > $final_ref->[0];                # salimos si $posicion ya no está dentro
  72.        
  73.             # gen    Chr    cuentas    posición
  74.             say $SALIDA join "\t", $final_ref->[1], $chr, $cuentas, $posicion
  75.         }
  76.     }
  77. }
  78.  
  79. close $INPUT1;
  80. close $SALIDA;
  81.  
  82. __END__
Coloreado en 0.006 segundos, usando GeSHi 1.0.8.4