Повторное использование одной ручки. Большое увеличение производительности?
В php script я делаю много разных запросов cUrl GET (сотни) для разных URL.
Повторное использование одного и того же ручка curl от curl_init улучшит производительность или будет ли это незначительно сравнить с временем отклика запросов cURL?
Я прошу, потому что в текущей архитектуре было бы непросто сохранить один и тот же дескриптор cUrl.
Спасибо,
Бенджамин
Ответы
Ответ 1
Это зависит от того, находятся ли URL-адреса на одном сервере или нет. Если они есть, одновременные запросы на тот же сервер будут повторно использовать соединение. см. CURLOPT_FORBID_REUSE.
Если URL-адреса иногда находятся на одном сервере, вам нужно отсортировать URL-адреса, поскольку кеш-соединение по умолчанию ограничено десятью или двадцатью соединениями.
Если они находятся на разных серверах, преимущество при использовании одного и того же дескриптора отсутствует.
С curl_multi_exec вы можете одновременно подключаться к различным серверам (параллельно). Даже тогда вам нужно несколько очередей, чтобы не использовать тысячи одновременных подключений.
Ответ 2
Crossposted from Должен ли я закрывать cURL или нет?, потому что я думаю, что это тоже актуально.
Я попробовал скалолазание с использованием нового дескриптора для каждого запроса и используя тот же дескриптор со следующим кодом:
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
for ($i = 0; $i < 100; ++$i) {
$rand = rand();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand);
curl_exec($ch);
curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
for ($i = 0; $i < 100; ++$i) {
$rand = rand();
curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand);
curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';
и получили следующие результаты:
Скручивание без повторного использования ручки: 8.5690529346466
Curl с повторным использованием ручки: 5.3703031539917
Таким образом, повторное использование одного и того же дескриптора обеспечивает значительное увеличение производительности при одновременном подключении к одному серверу. Я попытался подключиться к различным серверам:
$url_arr = array(
'http://www.google.com/',
'http://www.bing.com/',
'http://www.yahoo.com/',
'http://www.slashdot.org/',
'http://www.stackoverflow.com/',
'http://github.com/',
'http://www.harvard.edu/',
'http://www.gamefaqs.com/',
'http://www.mangaupdates.com/',
'http://www.cnn.com/'
);
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
foreach ($url_arr as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
foreach ($url_arr as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';
И получил следующий результат:
Скручивание без повторного использования ручки: 3.7672290802002
Curl с повторным использованием ручки: 3.0146431922913
Все еще довольно значительное увеличение производительности.
Ответ 3
У меня есть аналогичный сценарий, когда я отправляю данные на сервер. Он помещается в запросы ~ 100 строк, поэтому он создает много запросов. В контрольном прогоне я сравнил два подхода для 12.614 строк (127 запросов) плюс аутентификация и другой запрос на ведение домашнего хозяйства (всего 129 запросов).
Запросы передаются по сети на сервер в той же стране, а не на сайте. Они защищены TLS 1.2 (рукопожатие также принесет свои плоды, но, учитывая, что HTTPS становится все более предпочтительным выбором по умолчанию, это может даже сделать его более похожим на ваш сценарий).
С повторным использованием cURL:
один $curlHandle
, который curl_init()
'ed один раз, а затем изменен только с помощью CURLOPT_URL
и CURLOPT_POSTFIELDS
Run 1: ~42.92s
Run 3: ~41.52s
Run 4: ~53.17s
Run 5: ~53.93s
Run 6: ~55.51s
Run 11: ~53.59s
Run 12: ~53.76s
Avg: 50,63s / Std.Dev: 5,8s
TCP-Conversations / SSL Handshakes: 5 (Wireshark)
Без повторного использования cURL:
один curl_init
за запрос
Run 2: ~57.67s
Run 7: ~62.13s
Run 8: ~71.59s
Run 9: ~70.70s
Run 10: ~59.12s
Avg: 64,24s / Std. Dev: 6,5s
TCP-Conversations / SSL Handshakes: 129 (Wireshark)
Это не самый большой набор наборов данных, но можно сказать, что все "повторные" запуски работают быстрее, чем все "init". Среднее время показывает разницу почти 14 секунд.
Ответ 4
Это зависит от того, сколько запросов вы будете делать - накладные расходы на закрытие и повторное открытие каждого из них небрежны, но когда вы делаете тысячу? Может быть несколько секунд или более.
Я считаю, что curl_multi_init будет самым быстрым методом.
Все зависит от того, сколько запросов вам нужно сделать.
Ответ 5
проверьте это тоже
try {
$pool = new HttpRequestPool(
new HttpRequest($q1),
new HttpRequest($qn)
);
$pool->send();
foreach($pool as $request) {
$out[] = $request->getResponseBody();
}
} catch (HttpException $e) {
echo $e;
}