要件は次のとおりです。
事実1:レガシーシステムによって生成されたデータファイルがいくつかあります
事実2:新しいシステムによって生成されたデータファイルがいくつかあり、最終的にはレガシーシステムを置き換える必要があります
事実3:
- どちらのファイルもテキスト/ASCIIファイルであり、レコードは複数の行で構成されています。
- レコード内の各行は、フィールド名とフィールド値で構成されます。
- 行が表示される形式は1と2で異なりますが、フィールド名とフィールド値は、正規表現を使用して各行から抽出できます。
- フィールド名は1から2の間で変更できますが、それらを関連付けるマッピングがあります
- 出力ファイル内のレコードの順序は両方のシステムで同じである必要はないため、各レコードには一意の識別子があり、レガシーレコードを新しいレコードに関連付けるのに役立ちます。
- 比較する各ファイルは、最低10 MBで、平均的なケースは30〜35MBです。
事実4:新しいシステムを構築することを繰り返すとき、まったく同じ条件下で両方のシステムによって生成されたファイルを比較し、違いを調整する必要があります。
事実5:この比較は、高価なビジュアル差分ツールを使用して手動で行われています。これを支援するために、2つの異なるフィールド名を共通の名前にし、各ファイルの各レコードのフィールド名を並べ替えて、順番に同期するツールを作成しました(新しいファイルには、で無視される余分なフィールドを含めることができます)視覚的な違い)
事実6:人間が手動で比較を行っていることと、人間がミスを犯していることにより、タイムラインに大きな影響を与える誤ったポーズとネガティブが発生しています。
明らかに問題は、「ALG」と「DS」はどうあるべきかということです。
私が対処しなければならないシナリオ:
人々がdiffを視覚的に検査し続ける場合、これでは、既存のスクリプトのパフォーマンスは悲惨です。ほとんどの処理は、行の配列を辞書式順序でソートすることであるようです(配列要素の読み取り/フェッチ:Tie :: File :: FETCH、Tie :: File :: Cache :: lookupを正しい場所に配置して、ソートされるようにします: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";
それで私はそれについて考えました、そして私は、ある種のトライ、多分接尾辞のトライ/ PATRICIAトライであると信じています、それで挿入自体で各レコードのフィールドはソートされます。したがって、最終的な配列を一度に並べ替える必要はなく、コストは償却されます(私の側の推測)
その場合、別の問題が発生します-Tie :: Fileは配列を使用してファイル内の行を抽象化します-行をツリーに読み込んでから、それらを配列にシリアル化すると、追加のメモリと処理が必要になります/
質問は-タイドアレイをソートする現在のコストよりもコストがかかるでしょうか?