在我的应用程序中,我使用的是GuzzleHttp库,但这可能不是问题所在,但说出来并不好。
每分钟(使用cron)我需要从40多个地址获取数据,因此我尽可能快地使用GuzzleHttp lib。
Guzzle代码:
$client = new Client();
$rectangles = $this->db->query("SELECT * FROM rectangles");
$requests = function ($rectangles)
{
foreach($rectangles as $rectangle)
{
// some GEO coords (It's not important)
$left = $rectangle["lft"];
$right = $rectangle["rgt"];
$top = $rectangle["top"];
$bottom = $rectangle["bottom"];
$this->indexes[] = $rectangle;
$uri = "https://example.com/?left=$left&top=$top&right=$right&bototm=$bottom";
yield new Request("GET", $uri);
}
};
$pool = new Pool($client, $requests($rectangles), [
'concurrency' => 5,
'fulfilled' => function ($response, $index) {
$resp = $response->getBody();
$carray = json_decode($resp,true);
if($carray["data"] != null)
{
$alerts = array_filter($carray["data"], function($alert) {
return $alert["type"] == 'xxx';
});
$this->data = array_merge($this->data, $alerts);
$this->total_count += count($alerts);
}
},
'rejected' => function ($reason, $index) {},
]);
$promise = $pool->promise();
$promise->wait();
return $this->data;
当然,我做了一个基准。
1. getting data from another server 0.000xx sec
2. json_decode 0.001-0.0100 (this is probably the problem :-()
整个代码大约需要6-8秒。它取决于远程服务器上的数据量。
我认为Guzzle一直以异步方式执行请求,因此需要时间作为最长的请求。
(最慢的请求= 200毫秒==所有请求= 200毫秒) - 但这可能不是真的!或者我做错了。
我在json_decode中使用了一个关联数组(我觉得这是1秒的加速度(我不确定......)。
我的问题是,我可以将此代码更优化并加快速度吗?
我希望以最慢的请求(0.200秒)快速完成。
PS:我从网址获取的数据只是长JSON。谢谢!
编辑:我改变了并发性' => 5到'并发' => 100,现在持续时间约为2-4秒答案 0 :(得分:1)
首先,将Pool配置中的concurrency
值增加到您需要发送的请求总数。这应该没问题,实际上可能会让你更快。
关于以毫秒为单位加速json_decode,这可能取决于很多因素,包括您在处理JSON的服务器上使用的硬件以及不同大小的JSON数据。我不认为你可以用PHP编程来加速核心功能。我可能错了。
要查看的代码的另一部分是:$this->data = array_merge($this->data, $alerts);
您可以尝试使用循环代替。
您还在使用array_filter执行双重工作,其中数组内部的数组在array_merge之前被迭代。
所以,而不是:
if ($carray["data"] != null) {
$alerts = array_filter($carray["data"], function($alert) {
return $alert["type"] == 'xxx';
});
$this->data = array_merge($this->data, $alerts);
$this->total_count += count($alerts);
}
也许试试这个:
if ($carray["data"] != null) {
foreach ($carray["data"] as $cdata) {
if ($cdata["type"] == 'xxx') {
$this-data[] = $cdata;
$this->total_count++;
}
}
}