Требования:
Факт 1: у нас есть несколько файлов данных, созданных устаревшей системой
Факт 2: У нас есть несколько файлов данных, созданных новой системой, которые в конечном итоге должны заменить устаревшую
Факт 3:
- Оба файла являются текстовыми / ASCII файлами,
с записями, состоящими из
несколько строк.
- Каждая строка в записи состоит
имени поля и значения поля.
- Формат, в котором строки
представлены разные между 1
и 2, но имя поля и значение поля
можно извлечь из каждой строки
с помощью регулярных выражений
- Имена полей могут изменяться от 1 до
2, но у нас есть отображение, которое
связывает их
- Каждая запись имеет уникальный идентификатор
это помогает нам связать наследие
запись с новой записью в качестве заказа
записей в выходной файл нужно
не должно быть одинаковым в обеих системах.
- Каждый файл для сравнения является минимумом
10 МБ в среднем случае 30 - 35
MB
Факт 4: Как и когда мы выполняем итерацию при создании новой системы, нам необходимо сравнить файлы, созданные обеими системами в одинаковых условиях, и согласовать различия.
Факт 5: Это сравнение выполняется вручную с использованием дорогого инструмента визуального сравнения. Чтобы помочь в этом, я написал инструмент, который объединяет два разных имени поля в общее имя, а затем сортирует имена полей в каждой записи, в каждом файле, чтобы они синхронизировались по порядку (новые файлы могут иметь дополнительные поля, которые игнорируются в визуальная разница)
Факт 6: из-за того, что люди проводят сравнение вручную и из-за ошибок, допущенных человеком, мы получаем ложные позитивные и отрицательные стороны, которые существенно влияют на наши временные рамки.
Очевидно, вопрос в том, какими должны быть 'ALG' и 'DS'?
Сценарий, к которому я должен обратиться:
Там, где люди продолжают визуально проверять различия - при этом производительность ожидающего скрипта неутешительна - большая часть обработки заключается в сортировке массива строк в лексикографическом порядке (чтение / выборка элемента массива: 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";
Так что я подумал об этом, и я думаю, что-то вроде trie, может быть, trie / PATRICIA trie с суффиксом, так что при самой вставке поля в каждой записи сортируются.
Следовательно, мне не пришлось бы сортировать окончательный массив всего за один раз, и стоимость была бы амортизирована (спекуляция с моей стороны)
В этом случае возникает еще одна проблема - Tie :: File использует массив для абстрагирования строк в файле - чтение строк в дерево и последующая их сериализация обратно в массив потребует дополнительной памяти И обработки /
Вопрос в том, будет ли это стоить больше, чем текущая стоимость сортировки связанного массива?