gpt4 book ai didi

performance - 可能使用并发/异步/并行方法比较 2 个数据集

转载 作者:行者123 更新时间:2023-12-02 17:25:28 27 4
gpt4 key购买 nike

我目前正在尝试改进现有机制(比较来自 2 个来源的数据,在 perl5 中实现),并希望改用 perl6。

我的目标数据量范围是未压缩平面文件中的大约 20-30 GB。就行数而言,一个文件可以包含 1800 万到 2800 万行。每行大约有 40-50 列。

我每天都会进行这种类型的数据协调,从文件读取并填充哈希可能需要大约 10 分钟。读取这两个文件并填充哈希大约花费 20 分钟。

比较过程大约需要 30-50 分钟,包括迭代哈希、收集所需结果以及写入输出文件(csv、psv)。

总而言之,在具有 256GB RAM 的 32 核双 Xeon CPU 服务器(包括间歇性服务器负载)上执行该过程可能需要 30 分钟到 60 分钟。

现在我正在尝试进一步缩短总处理时间。

这是我当前使用 perl5 的单线程方法。

  1. 从 2 个来源(比方说 s1 和 s2)一一获取数据,并根据键值对填充我的哈希值。数据源可以是平面 csv 或 psv 文件,也可以是通过 DBI 客户端的数据库查询数组结果的数组。数据一开始总是未排序的。
  2. 具体来说,我逐行读取文件,拆分字段,并为键、值对选择所需的索引并插入到哈希中。
  3. 收集数据并使用所需的键/值对填充哈希后,我开始比较和收集结果(主要比较 s2 与 s1 中缺失或不同的内容,反之亦然)。
  4. 将输出转储到 Excel 文件中(如果行数很大,如约 100 万或更多,则成本非常高)或简单的 CSV 中(操作成本低。首选方法>).

我想知道是否可以以某种方式并行执行第一步,即立即从两个源收集数据并填充我的全局哈希,然后继续比较和转储输出?

perl6 可以提供哪些选项来处理这种情况?我读过有关使用 perl6 的并发、异步和并行操作的内容,但我不太确定哪一个可以帮助我。

我非常感谢任何有关此事的一般指导。我希望我能很好地解释我的问题,但遗憾的是我没有太多可以展示的到目前为止我尝试了什么?原因是我才刚刚开始解决这个问题。我只是无法超越单线程方法并需要一些帮助。

谢谢。

编辑

由于社区认为我现有的问题陈述“过于宽泛” - 请允许我尝试在下面强调我的痛点:

  1. 如果可能的话,我想利用所有 32 个核心进行文件比较。我只是无法提出策略或初步想法。
  2. 哪些类型的新技术可用或适用于 perl6 来解决此问题或此类问题。
  3. 如果我生成 2 个进程来读取文件并收集数据 - 是否可以将结果作为数组或散列返回?
  4. 是否可以并行比较数据(存储在哈希中)?

我目前的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:]$

最佳答案

如果您有现有且可用的工具链,则无需全部重写即可使用 Perl6。它的并行机制也适用于外部进程。考虑一下

allnum.pl6

use v6;

my @processes =
[ "num1.txt", "num2.txt", "num3.txt", "num4.txt", "num5.txt" ]
.map( -> $filename {
[ $filename, run "perl", "num.pl", $filename, :out ];
})
.hyper;

say "Lazyness Here!";
my $time = time;
for @processes
{
say "<{$_[0]} : {$_[1].out.slurp}>";
}
say time - $time, "s";

num.pl

use warnings;
use strict;

my $file = shift @ARGV;
my $start = time;
my $result = 0;

open my $in, "<", $file or die $!;
while (my $thing = <$in>)
{
chomp $thing;
$thing =~ s/ //g;
$result = ($result + $thing) / 2;
}
print $result, " : ", time - $start, "s";

在我的系统上

C:\Users\holli\tmp>perl6 allnum.pl6
Lazyness Here!
<num1.txt : 7684.16347578616 : 3s>
<num2.txt : 3307.36261498186 : 7s>
<num3.txt : 5834.32817942962 : 10s>
<num4.txt : 6575.55944995197 : 0s>
<num5.txt : 6157.63100049619 : 0s>
10s

文件设置如下

C:\Users\holli\tmp>perl -e "for($i=0;$i<10000000;$i++) { print chr(32) ** 100, int(rand(1000)), chr(32) ** 100, qq(\n); }">num1.txt
C:\Users\holli\tmp>perl -e "for($i=0;$i<20000000;$i++) { print chr(32) ** 100, int(rand(1000)), chr(32) ** 100, qq(\n); }">num2.txt
C:\Users\holli\tmp>perl -e "for($i=0;$i<30000000;$i++) { print chr(32) ** 100, int(rand(1000)), chr(32) ** 100, qq(\n); }">num3.txt
C:\Users\holli\tmp>perl -e "for($i=0;$i<400000;$i++) { print chr(32) ** 100, int(rand(1000)), chr(32) ** 100, qq(\n); }">num4.txt
C:\Users\holli\tmp>perl -e "for($i=0;$i<5000;$i++) { print chr(32) ** 100, int(rand(1000)), chr(32) ** 100, qq(\n); }">num5.txt

关于performance - 可能使用并发/异步/并行方法比较 2 个数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52082308/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com