В настоящее время я пытаюсь улучшить существующий механизм ( для сравнения данных из 2 источников, реализованный в perl5 ) и хотел бы вместо него использовать perl6.
Мой целевой объем данных составляет около 20-30 ГБ в несжатых плоских файлах.
С точки зрения строк, файл может содержать от 18 до 28 миллионов строк.
В каждой строке около 40-50 столбцов.
Я выполняю такой тип выверки данных ежедневно, и для чтения из файла и заполнения хеша может потребоваться ~ 10 минут. ~ 20 минут потрачено на чтение обоих файлов и заполнение хеша.
Процесс сравнения занимает около 30-50 минут, включая итерации по хешу, сбор желаемых результатов и запись в выходной файл (csv, psv).
В целом процесс может занять от 30 минут до 60 минут на 32-ядерном двухъядерном процессоре xeon с 256 ГБ ОЗУ, включая прерывистую загрузку сервера.
Теперь я пытаюсь сократить общее время обработки еще больше.
Вот мой текущий однопоточный подход с использованием perl5.
- выборка данных из 2 источников (, скажем, s1 и s2 ) один за другим и заполнение моего хэша на основе пар ключ-значение. Источником данных может быть либо плоский CSV-файл, либо PSV-файл, либо запрос массива массива запроса базы данных через клиент DBI. Для начала данные всегда сортируются.
- Если быть точным, я читаю файл построчно, разделяю поля и выбираю нужные индексы для ключа, пары значений и вставляю в хеш.
- После сбора данных и заполнения хэша желаемыми парами ключ / значение, я начинаю сравнивать и собирать результаты ( основное сравнение с тем, что отсутствует или отличается в s2 по сравнению с s1 и наоборот ).
- вывод дампа в файл Excel ( очень дорого, если число строк велико, как ~ 1 миллион или больше ) или в простом CSV ( дешевая операция. Предпочтительный метод ) .
Мне было интересно, смогу ли я как-нибудь сделать первый шаг параллельно, то есть собрать данные из обоих источников одновременно и заполнить мой глобальный хэш, а затем перейти к сравнению и выводу вывода?
Какие опции может предоставить perl6 для решения этой ситуации? Я читал о параллелизме, асинхронных и параллельных операциях с использованием perl6, но я не уверен, какой из них мне поможет.
Я был бы очень признателен за любые общие указания по этому вопросу. Надеюсь, я хорошо объяснил свою проблему, но, к сожалению, мне нечего показать по , что я пробовал до сих пор? , и причина в том, что я только начинаю решать эту проблему. Я просто не могу понять, что такое однопоточный подход, и мне нужна помощь.
Спасибо.
EDIT
Поскольку мое существующее изложение проблемы было признано сообществом как «слишком широкое» - позвольте мне попытаться выделить мои болевые точки ниже:
- Я бы хотел сравнить файлы, используя все 32 ядра, если это возможно. Я просто не могу придумать стратегию или первоначальную идею.
- Какие новые методы доступны или применимы с perl6 для решения этой проблемы или типа проблемы.
- Если я порождаю 2 процесса для чтения файла (ов) и сбора данных - возможно ли вернуть результат в виде массива или хеша?
- Можно ли сравнить данные (, хранящиеся в хэше ) параллельно?
Моя текущая логика сравнения p5 показана ниже для справки. Надеюсь, что это поможет, и не позволяйте этому вопросу закрыться.
package COMP;
use strict;
use Data::Dumper;
sub comp
{
my ($data,$src,$tgt) = @_;
my $result = {};
my $ms = ($result->{ms} = {});
my $mt = ($result->{mt} = {});
my $diff = ($result->{diff} = {});
foreach my $key (keys %{$data->{$src}})
{
my $src_val = $data->{$src}{$key};
my $tgt_val = $data->{$tgt}{$key};
next if ($src_val eq $tgt_val);
if (!exists $data->{$tgt}{$key}) {
push (@{$mt->{$key}}, "$src_val|NULL");
}
if (exists $data->{$tgt}{$key} && $src_val ne $tgt_val) {
push (@{$diff->{$key}}, "$src_val|$tgt_val")
}
}
foreach my $key (keys %{$data->{$tgt}})
{
my $src_val = $data->{$src}{$key};
my $tgt_val = $data->{$tgt}{$key};
next if ($src_val eq $tgt_val);
if (!exists $data->{$src}{$key}) {
push (@{$ms->{$key}},"NULL|$tgt_val");
}
}
return $result;
}
1;
Если кто-то захочет попробовать, вот пример выходных данных и используемый тестовый скрипт.
вывод сценария
[User@Host:]$ perl testCOMP.pl
$VAR1 = {
'mt' => {
'Source' => [
'source|NULL'
]
},
'ms' => {
'Target' => [
'NULL|target'
]
},
'diff' => {
'Sunday_isit' => [
'Yes|No'
]
}
};
Тестовый скрипт
[User@Host:]$ cat testCOMP.pl
#!/usr/bin/env perl
use lib $ENV{PWD};
use COMP;
use strict;
use warnings;
use Data::Dumper;
my $data2 = {
f1 => {
Amitabh => 'Bacchan',
YellowSun => 'Yes',
Sunday_isit => 'Yes',
Source => 'source',
},
f2 => {
Amitabh => 'Bacchan',
YellowSun => 'Yes',
Sunday_isit => 'No',
Target => 'target',
},
};
my $result = COMP::comp ($data2,'f1','f2');
print Dumper $result;
[User@Host:]$