В настоящее время я пытаюсь улучшить существующий механизм (для сравнения данных из 2 источников, реализованных в perl5) и хотел бы использовать perl6 вместо этого.
Объем целевых данных составляет около 20-30 ГБ в несжатых плоских файлах. В терминах строк файл может содержать от 18 до 28 миллионов строк. Он имеет около 40-50 столбцов в строке.
Я делаю этот тип согласования данных ежедневно, и для чтения из файла и заполнения хэша может потребоваться около 10 минут. ~ 20 минут потрачено на чтение обоих файлов и заполнение хэша.
процесс сравнения занимает около 30-50 минут, включая итерацию по хэшу, сбор желаемого результата (ов) и запись в выходной файл (csv, psv).
В целом, для выполнения этого процесса может потребоваться от 30 минут до 60 минут на 32-ядерном процессоре с двумя xeon cpu с 256 ГБ ОЗУ, включая прерывистую нагрузку на сервер.
Теперь я пытаюсь еще больше сократить время обработки.
Вот мой текущий однопоточный подход с использованием perl5.
- извлекать данные из 2 источников (скажем, s1 и s2) один за другим и заполнять мой хэш на основе пар ключ-значение. Источником данных может быть либо плоский CSV файл, либо psv файл, либо результат запроса массива Array из массива через клиент DBI. Для начала всегда данные не сортируются.
- Чтобы быть конкретным, я читал файл строки за строкой, разделял поля и выбирал нужные индексы для пары ключей, значений и вставлял в хэш.
- После сбора данных и заполнения хэша с помощью желаемых пар ключ/значение, я начинаю сравнивать и собирать результаты (главное сравнение того, что отсутствует или отличается в s2 по s1 и наоборот).
- дамп-выход в файле excel (очень дорогостоящий, если нет строк больших, например, ~ 1 млн или более) или в простой CSV (дешевая операция. предпочтительный метод).
Мне было интересно, смогу ли я как-нибудь сделать первый шаг параллельно, т.е. собрать данные из обоих источников сразу и заполнить мой глобальный хэш, а затем перейти к сравнению и вывести вывод?
Какие варианты могут помочь решить эту ситуацию? Я читал о параллелизмах, асинхронных и параллельных операциях с использованием perl6, но я не настолько уверен, что могу помочь мне здесь.
Я бы очень признателен за любое общее руководство по этому вопросу. Надеюсь, я хорошо объяснил свою проблему, но, к сожалению, мне нечего показать, что я пробовал до сих пор? и причина в том, что я только начинаю заниматься этим. Я просто не могу увидеть прошлый однопоточный подход и нуждаюсь в некоторой помощи.
Благодарю.
РЕДАКТИРОВАТЬ
Поскольку мое существующее выражение о проблеме было сочтено сообществом "слишком широким", позвольте мне попытаться выделить мои пункты боли ниже:
- Я хотел бы сделать сравнение файлов, используя все 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;
Если кто-то хочет попробовать, вот пример вывода и используемый тестовый скрипт.
выход скрипта
[[email protected]:]$ perl testCOMP.pl
$VAR1 = {
'mt' => {
'Source' => [
'source|NULL'
]
},
'ms' => {
'Target' => [
'NULL|target'
]
},
'diff' => {
'Sunday_isit' => [
'Yes|No'
]
}
};
Тест-сценарий
[[email protected]:]$ 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;
[[email protected]:]$