2009-05-20 6 views
1

Les exigences sont les suivantes:Comparaison des enregistrements dans le fichier et les rapports statistiques - Scénario 1

Fait 1: Nous avons des fichiers de données produites par un système existant

Fait n ° 2: Nous avons des fichiers de données produites par une nouvelle système qui devrait remplacer à terme l'héritage d'un

Fait n ° 3:

  1. les deux fichiers sont des fichiers texte/ASCII, documents étant composé de 0.123.plusieurs lignes.
  2. Chaque ligne, dans un enregistrement, consiste en d'un nom de champ et d'une valeur de champ.
  3. Le format dans lequel les lignes sont présentées sont différentes entre 1 et 2, mais nomchamp et fieldvalue peuvent être extraites de chaque ligne par l'utilisation d'expressions régulières
  4. Les noms de champs peuvent changer entre 1 et 2, mais nous avons une cartographie qui les concerne
  5. Chaque enregistrement possède un identifiant unique qui nous aide relions le record héritage avec un nouveau record de commander d'enregistrements dans le fichier de sortie doivent pas identiques dans les deux systèmes.
  6. Chaque fichier à comparer est un minimum de 10 Mo à un cas moyen de 30 - 35 MB

Fait n ° 4: Comme et quand nous parcourons que la construction du nouveau système, nous aurions besoin de comparer les fichiers produits par les deux systèmes dans des conditions exactement identiques et rapprocher les différences. Fait 5: Cette comparaison est faite manuellement en utilisant un coûteux outil de comparaison visuelle. Pour aider à cela, j'ai écrit un outil qui amène les deux différents noms de champs dans un nom commun, puis trie les noms de champs dans chaque enregistrement, dans chaque fichier, afin qu'ils se synchronisent dans l'ordre (les nouveaux fichiers peuvent avoir des champs ignorés). la différence visuelle)

Fait 6: En raison de la comparaison faite manuellement par des humains, et des erreurs humaines, nous obtenons de faux posetifs et négatifs qui ont un impact significatif sur nos délais.

De toute évidence, la question est: que devraient être 'ALG' et 'DS'?

Le scénario que je dois répondre:

Si les gens continuent d'inspecter les diff visuellement - dans ce domaine, la performance du script exsiting est lamentable - la plupart du traitement semble être en triant le tableau de lignes ordre lexicographique (lire/récupérer un élément de tableau: Tie :: File :: FETCH, Tie :: File :: Cache :: chercher et le placer à l'endroit correct pour qu'il soit trié: Tie :: File :: Cache :: insert, tie :: File :: Heap :: insert)

use strict; 
use warnings; 

use Tie::File; 

use Data::Dumper; 

use Digest::MD5 qw(md5_hex); 

# open an existing file in read-only mode 
use Fcntl 'O_RDONLY'; 

die "Usage: $0 <unsorted input filename> <sorted output filename>" if ($#ARGV < 1); 

our $recordsWrittenCount = 0; 
our $fieldsSorted = 0; 

our @array; 

tie @array, 'Tie::File', $ARGV[0], memory => 50_000_000, mode => O_RDONLY or die "Cannot open $ARGV[0]: $!"; 

open(OUTFILE, ">" . $ARGV[1]) or die "Cannot open $ARGV[1]: $!"; 

our @tempRecordStorage =(); 

our $dx = 0; 

# Now read in the EL6 file 

our $numberOfLines = @array; # accessing @array in a loop might be expensive as it is tied?? 

for($dx = 0; $dx < $numberOfLines; ++$dx) 
{ 
    if($array[$dx] eq 'RECORD') 
    { 
     ++$recordsWrittenCount; 

     my $endOfRecord = $dx; 

     until($array[++$endOfRecord] eq '.') 
     { 
      push @tempRecordStorage, $array[$endOfRecord]; 
      ++$fieldsSorted; 
     } 

     print OUTFILE "RECORD\n"; 

     local $, = "\n"; 
     print OUTFILE sort @tempRecordStorage; 
     @tempRecordStorage =(); 

     print OUTFILE "\n.\n"; # PERL does not postfix trailing separator after the last array element, so we need to do this ourselves) 

     $dx = $endOfRecord;  
    } 
} 

close(OUTFILE); 

# Display results to user 

print "\n[*] Done: " . $fieldsSorted . " fields sorted from " . $recordsWrittenCount . " records written.\n"; 

donc je pensais à ce sujet et je crois, une sorte si une structure arborescente, peut-être le suffixe Trie/PATRICIA Trie, de sorte que lors de l'insertion itsel f les champs de chaque enregistrement sont triés. Par conséquent, je n'aurais pas à trier le tableau final en une seule fois et le coût serait amorti (une spéculation de ma part)

Un autre problème se pose dans ce cas - Tie :: File utilise tableau pour les lignes abstraites dans un fichier - lire des lignes dans un arbre et les sérialiser ensuite dans un tableau nécessiterait une mémoire supplémentaire ET un traitement/

La question est - cela coûterait-il plus cher que le coût actuel du tri du tableau lié?

Répondre

2

Tie :: Le fichier est très lent. Il y a deux raisons à cela: Premièrement, les variables liées sont significativement plus lentes que les variables standard. L'autre raison est que dans le cas de Tie :: File les données de votre tableau sont sur le disque plutôt qu'en mémoire. Cela ralentit considérablement l'accès. Le cache de Tie :: File peut aider les performances dans certaines circonstances, mais pas lorsque vous faites simplement une boucle sur le tableau un élément à la fois comme vous le faites ici. (Le cache n'aide que si vous revisitez le même index.) Le temps d'utiliser Tie :: File est quand vous avez un algorithme qui nécessite d'avoir toutes les données en mémoire à la fois mais vous n'avez pas assez de mémoire pour le faire. Puisque vous ne traitez le fichier qu'une ligne à la fois en utilisant Tie :: File n'est pas seulement inutile, c'est dangereux.

Je ne pense pas qu'un trie est le bon choix ici. J'utiliserais un simple HoH (hachage de hash) à la place. Vos fichiers sont suffisamment petits pour que vous puissiez tout enregistrer en même temps. Je recommande l'analyse syntaxique qui ressemble à chaque fichier et la construction d'un hachage ceci:

%data = (
    id1 => { 
    field1 => value1, 
    field2 => value2, 
    }, 
    id2 => { 
    field1 => value1, 
    field2 => value2, 
    }, 
); 

Si vous utilisez vos applications pour normaliser les noms de terrain tout en construisant la structure de données, il sera plus facile de faire la comparaison.

Pour comparer les données, faites ceci:

  1. effectuer une comparaison de jeu des clés des deux hash. Cela devrait générer trois listes: les ID présents uniquement dans les données héritées, les ID présents uniquement dans les nouvelles données et les ID présents dans les deux.
  2. Indique les listes d'ID qui n'apparaissent que dans un ensemble de données. Ce sont des enregistrements qui n'ont pas d'enregistrement correspondant dans l'autre ensemble de données.
  3. Pour les ID dans les deux ensembles de données, comparez les données pour chaque champ ID par champ et signalez les différences.
Questions connexes