2012-07-24 4 views
1

Je cherche des suggestions sur la façon d'optimiser ce script Perl.Perl Optimization Recommandation

J'ai ce script pour faire un reformatage mineur d'un fichier. Le script procède comme suit:

  1. Lit un "|" fichier délimité à partir de STDIN
  2. Supprime les espaces de fin,
  3. Enlève "NULL" chaîne de texte
  4. Transforme des colonnes avec des dates au format "AAAAMMJJ" de "AAAA-MM-JJ hh: mm" format de date.
  5. Imprime vers STDOUT et fait un kluge pour éviter de perdre la dernière colonne de données quand elle est NULL. Le nombre de colonnes doit être le même pour chaque ligne.

entrée de l'échantillon:

.091590.S   |CHF|SWX|2011-05-23 00:00|     77.25|     NULL|     NULL|  78.620000000000005|    NULL 
.091590.S   |CHF|SWX|2011-05-24 00:00|  77.599999999999994|     NULL|     NULL|     77.25|    NULL 
.091590.S   |CHF|SWX|2011-05-25 00:00|  77.760000000000005|     NULL|     NULL|  77.599999999999994|    NULL 
.091590.S   |CHF|SWX|2011-05-26 00:00|  77.430000000000007|     NULL|     NULL|  77.760000000000005|    NULL 
.091590.S   |CHF|SWX|2011-05-27 00:00|  77.909999999999997|     NULL|     NULL|  77.430000000000007|    NULL 
.091590.S   |CHF|SWX|2011-05-30 00:00|  78.060000000000002|     NULL|     NULL|  77.909999999999997|    3506 

FormattingScript.pl [col]

Où [col] peut être un nombre unique ou une liste de numéros délimités par une virgule. Cette entrée détermine la ou les colonnes nécessitant une conversion de date.

@updcol = split(',',@ARGV[0]); 

while (<STDIN>) 
{ 
     s/.$/|DATAEND/g; ## USING THIS TO KEEP FROM TRUNCATING NULL LAST COLUMN 
     s/^\s*//g; 
     s/\s*$//g; 
     s/\s*\|/\|/g; 
     s/\|\s*/\|/g; 
     s/\|NULL\|/\|\|/g; 
     s/\|NULL\s*$/\|/g; 
     s/\|NULL\s*/\|/g; 
     s/\|NULL$/\|/g; 
     @dataline = split('\|',$_); 
if (@updcol[0] != 999) { ## REFORMAT DATES IF PARAM IS NOT 999 
     foreach my $col (@updcol) { 
     $dataline[$col]=substr($dataline[$col],0,4).substr($dataline[$col],5,2).substr($dataline[$col],8,2); 
     }} 
     $dataline[-1]=""; 
     $line=join('|',@dataline); 
     print substr($line,0,-1)."\n"; 
} 

exit 0; 

Exemple de sortie:

.091590.S|CHF|SWX|2011-05-23 00:00|77.25|||78.620000000000005| 
.091590.S|CHF|SWX|2011-05-24 00:00|77.599999999999994|||77.25| 
.091590.S|CHF|SWX|2011-05-25 00:00|77.760000000000005|||77.599999999999994| 
.091590.S|CHF|SWX|2011-05-26 00:00|77.430000000000007|||77.760000000000005| 
.091590.S|CHF|SWX|2011-05-27 00:00|77.909999999999997|||77.430000000000007| 
.091590.S|CHF|SWX|2011-05-30 00:00|78.060000000000002|||77.909999999999997|3506 
+2

Veuillez vous rappeler [les règles du Club Optimisation] (http://stackoverflow.com/a/177132/554546). Pourquoi avez-vous besoin d'optimiser ce programme? –

Répondre

9

Les Optimisations vont être micro, ce qui signifie que vous aurez besoin de prendre de référence et commencer à tester les différentes façons de faire la même chose.

Vous auriez avantage à mieux nettoyer le code qu'à l'optimiser.

my @date_cols = split(/,/, shift(@ARGV)); 

while (<>) { 
    #chomp; # Redundant. 
    my @fields = split(/\|/, $_, -1); 

    for (@fields) { 
     s/^\s+//; 
     s/\s+\z//; 
     s/^NULL\z//; 
    } 

    for (@fields[@date_cols]) { 
     s/^(....)-(..)-(..).*/$1$2$3/s; 
    } 

    print(join('|', @fields), "\n"); 
} 
+2

Notez le 3ème argument de ['split'] (http://perldoc.perl.org/functions/split.html). – ikegami

+0

Correction d'un petit bug. Suppression de "chomp" redondant. – ikegami

+0

Merci @ikegami. C'était un exercice très utile. Cela me rappelle combien je dois encore apprendre. J'ai dû ajouter au lieu de <> pour que le script reconnaisse à la fois le paramètre que j'ai passé et le flux. – DataTsar

2

Vous pouvez être en mesure d'optimiser vos expressions rationnelles à l'aide Regexp::Assemble. Cela vous permettra de combiner toutes vos regexes dans une regex qui s'exécutera probablement plus vite que plusieurs expressions régulières.