gpt4 book ai didi

Perl 同时下载 HTTP::Async 和 Net::Async::HTTP 太慢

转载 作者:可可西里 更新时间:2023-11-01 15:11:16 26 4
gpt4 key购买 nike

我正在尝试与脚本并行获取大约 7 个 url:第一个在下面,使用 HTTP::Async,第二个是 on pastebin , 与 Net::Async::HTTP。问题是我得到了完全相同的计时结果——所有 url 列表大约需要 8..14 秒。与从 shell 启动的 curl+xargs 相比,它的速度慢得令人无法接受,它在不到 3 秒的时间内用 10-20 个“线程”完成了所有工作。例如,第一个脚本中的 Devel::Timer 显示最大队列长度甚至小于 6 ($queue->in_progress_count<=5, $queue->to_send_count=始终为 0)。所以,看起来带有 $queue->add 的 foreach 执行速度太慢,我不知道为什么。我使用 Net::Async::HTTP(pastebin 上的第二个脚本)遇到的情况完全相同,它比第一个还要慢。

那么,请问有人知道我做错了什么吗?至少与从 shell 启动的 curl+xargs 相比,我怎样才能获得并发下载速度?

#!/usr/bin/perl -w
use utf8;
use strict;
use POSIX qw(ceil);
use XML::Simple;
use Data::Dumper;
use HTTP::Request;
use HTTP::Async;
use Time::HiRes qw(usleep time);
use Devel::Timer;

#settings
use constant passwd => 'ultramegahypapassword';
use constant agent => 'supa agent dev.alpha';
use constant timeout => 10;
use constant slots => 10;
use constant debug => 1;

my @qids;
my @xmlz;
my $queue = HTTP::Async->new(slots => slots,max_request_time => 10, timeout => timeout, poll_interval => 0.0001);
my %responses;
my @urlz = (
'http://testpodarki.afghanet/api/products/4577',
'http://testpodarki.afghanet/api/products/4653',
'http://testpodarki.afghanet/api/products/4652',
'http://testpodarki.afghanet/api/products/4571',
'http://testpodarki.afghanet/api/products/4572',
'http://testpodarki.afghanet/api/products/4666',
'http://testpodarki.afghanet/api/products/4576',
'http://testpodarki.afghanet/api/products/4574',
'http://testpodarki.afghanet/api/products/4651',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[3294]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[3294]',
'http://testpodarki.afghanet/api/combinations/?display=full&filter[id_product]=[4577]',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4577]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4577]',
'http://testpodarki.afghanet/api/product_option_values/188',
'http://testpodarki.afghanet/api/product_option_values/191',
'http://testpodarki.afghanet/api/product_option_values/187',
'http://testpodarki.afghanet/api/product_option_values/190',
'http://testpodarki.afghanet/api/product_option_values/189',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4653]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4653]',
'http://testpodarki.afghanet/api/images/products/4577/12176',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4652]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4652]',
'http://testpodarki.afghanet/api/images/products/4653/12390',
'http://testpodarki.afghanet/api/combinations/?display=full&filter[id_product]=[4571]',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4571]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4571]',
'http://testpodarki.afghanet/api/images/products/4652/12388',
'http://testpodarki.afghanet/api/product_option_values/175',
'http://testpodarki.afghanet/api/product_option_values/178',
'http://testpodarki.afghanet/api/product_option_values/179',
'http://testpodarki.afghanet/api/product_option_values/180',
'http://testpodarki.afghanet/api/product_option_values/181',
'http://testpodarki.afghanet/api/images/products/3294/8965',
'http://testpodarki.afghanet/api/product_option_values/176',
'http://testpodarki.afghanet/api/product_option_values/177',
'http://testpodarki.afghanet/api/combinations/?display=full&filter[id_product]=[4572]',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4572]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4572]',
'http://testpodarki.afghanet/api/product_option_values/176',
'http://testpodarki.afghanet/api/product_option_values/181',
'http://testpodarki.afghanet/api/product_option_values/180',
'http://testpodarki.afghanet/api/images/products/4571/12159',
'http://testpodarki.afghanet/api/product_option_values/177',
'http://testpodarki.afghanet/api/product_option_values/179',
'http://testpodarki.afghanet/api/product_option_values/175',
'http://testpodarki.afghanet/api/product_option_values/178',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4666]',
'http://testpodarki.afghanet/api/combinations/?display=full&filter[id_product]=[4576]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4666]',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4576]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4576]',
'http://testpodarki.afghanet/api/images/products/4572/12168',
'http://testpodarki.afghanet/api/product_option_values/185',
'http://testpodarki.afghanet/api/product_option_values/182',
'http://testpodarki.afghanet/api/product_option_values/184',
'http://testpodarki.afghanet/api/product_option_values/183',
'http://testpodarki.afghanet/api/product_option_values/186',
'http://testpodarki.afghanet/api/images/products/4666/12413',
'http://testpodarki.afghanet/api/combinations/?display=full&filter[id_product]=[4574]',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4574]',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4574]',
'http://testpodarki.afghanet/api/product_option_values/177',
'http://testpodarki.afghanet/api/product_option_values/181',
'http://testpodarki.afghanet/api/images/products/4576/12174',
'http://testpodarki.afghanet/api/product_option_values/176',
'http://testpodarki.afghanet/api/product_option_values/180',
'http://testpodarki.afghanet/api/product_option_values/179',
'http://testpodarki.afghanet/api/product_option_values/175',
'http://testpodarki.afghanet/api/product_option_values/178',
'http://testpodarki.afghanet/api/specific_prices/?display=full&filter[id_product]=[4651]',
'http://testpodarki.afghanet/api/images/products/4574/12171',
'http://testpodarki.afghanet/api/stock_availables/?display=full&filter[id_product]=[4651]',
'http://testpodarki.afghanet/api/images/products/4651/12387'
);

my $timer = Devel::Timer->new();


foreach my $el (@urlz) {
my $request = HTTP::Request->new(GET => $el);
$request->header(User_Agent => agent);
$request->authorization_basic(passwd,'');
push @qids,$queue->add($request);
$timer->mark("pushed [$el], to_send=".$queue->to_send_count().", to_return=".$queue->to_return_count().", in_progress=".$queue->in_progress_count());
}

$timer->mark('requestz pushed');

while ($queue->in_progress_count) {
usleep(2000);
$queue->poke();
}

$timer->mark('requestz complited');

process_responses();


$timer->mark('responzez processed');

foreach my $q (@xmlz) {
# print ">>>>>>".Dumper($q)."<<<<<<<<\n";
}

$timer->report();
print "\n\n";

最佳答案

我最好的成绩 HTTP::Async远远超过 4 秒,最多超过 5 秒。据我所知,这种方法不是必需的,这里是一个简单的 fork 示例,它需要 2 秒多一点,最多不到 3 秒。

它使用 Parallel::ForkManagerLWP::UserAgent用于下载。

use warnings;
use strict;
use Path::Tiny;
use LWP::UserAgent;
use Parallel::ForkManager;

my @urls = @{ get_urls('https://pastebin.com/raw/VyhMEB3w') };

my $pm = new Parallel::ForkManager(60); # max of 60 processes at a time
my $ua = LWP::UserAgent->new;
print "Downloading ", scalar @urls, " files.\n";

my $dir = 'downloaded_files/';
mkdir $dir if not -d $dir;
my $cnt = 0;
foreach my $link (@urls)
{
my $file = "$dir/file_" . ++$cnt . '.txt';

$pm->start and next; # child process

# add code needed for actual pages (authorization etc)
my $response = $ua->get($link);
if ($response->is_success) {
path($file)->spew_utf8($response->decoded_content);
}
else { warn $response->status_line }

$pm->finish; # child exit
}
$pm->wait_all_children;

sub get_urls {
my $resp = LWP::UserAgent->new->get($_[0]);
return [ grep /^http:/, split /\s*'?,?\s*\n\s*'?/, $resp->decoded_content ];
};

文件是使用 Path::Tiny 编写的.它的 path 构建一个对象,spew 例程写入文件。

作为引用,顺序下载大约需要 26 秒。

最大进程数设置为 30 时,这需要 4 多秒,而 60 时,则需要 2 秒多一点,与(最多)90 时大致相同。此测试中有 70 个 url。

在具有良好网络连接的 4 核笔记本电脑上进行测试。 (这里的 CPU 并不是那么重要。)测试在多天多次重复运行。


与问题方法的比较

最好的 HTTP::Async 结果比上面的慢两倍左右。他们有 30-40 个“插槽”,因为对于更高的数字,时间会增加,这让我感到困惑。该模块使用 select 进行多路复用,通过 Net::HTTP::NB (Net::HTTP 的非阻塞版本)。虽然 select“不能很好地扩展”这涉及数百个套接字,但我希望能够在这个网络绑定(bind)问题上使用超过 40 个。简单的 fork 方法可以。

此外,select 被认为是一种监控套接字的缓慢方法,而 fork 甚至不需要它,因为每个进程都有自己的 url。 (当连接很多的时候,这可能会导致模块的开销?) Fork 的固有开销是固定的,与网络访问相比相形见绌。如果我们进行(许多)数百次下载,系统可能会因进程而变得紧张,但 select 也不会很好。

最后,基于select 的方法一次只下载一个文件,当请求被添加时,通过打印可以看到效果——我们可以看到延迟。 fork 下载并行进行(在这种情况下,所有 70 个同时没有问题)。然后会出现网络或磁盘瓶颈,但与 yield 相比微不足道。

更新:我插入它使站点和进程的数量翻了一番,没有看到操作系统/CPU 压力的迹象,并保持了平均速度。

所以我想说,如果您需要每隔一秒剃一次 mustache ,就用 fork 。但是,如果这不是关键,并且 HTTP::Async(或类似的)还有其他好处,那么就满足于(稍微)更长的下载时间。


表现良好的HTTP::Async 代码最终变得很简单

foreach my $link ( @urls ) {  
$async->add( HTTP::Request->new(GET => $link) );
}
while ( my $response = $async->wait_for_next_response ) {
# write file (or process otherwise)
}

我还尝试调整标题和时间。 (这包括按照 $request->header(Connection => 'close') 的建议删除 keep-alive,但没有效果。)

关于Perl 同时下载 HTTP::Async 和 Net::Async::HTTP 太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43024722/

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