php curl multithread

Пару недель назад на ачате видел такой пост, якобы curl multithread это для галочки и никакого прироста в скорости оно не дает… причем пост от человека с репой…
Специально для таких скептиков и по собственному интересу (насколько полезны мультизапросы) потратил время на тестирование 3 вариантов:
php curl + javascript (искусственные мультизапросы)
php curl и цикл foreach
php multithread curl

Тестировал на обычной задаче — проверка прокси… Прокси взял специально выдуманные, дабы глюки на этих проксях не могли влиять на результат тестирования. Во всех трех случаях курл запрос аналогичен — одинаковые действия, одинаковые прокси. Тестил и все вместе и по очереди и по отдельности…
Вот таким кодом:

<?php

function showtime($start1)
{
    $end1=gettimeofday();
    $totaltime1 = (float)($end1['sec'] - $start1['sec']) + ((float)($end1['usec'] -$start1['usec'])/1000000);
    echo $totaltime1;
}
$proxies = array('123.123.123.123:81', '120.123.124.123:33','141.123.123.123:505','123.123.127.123:11','183.123.123.121:2224');
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    </head>
    <body>
<?php
//javascript + php
$start = gettimeofday();
if(isset($_GET['js'])):
{
    $c = curl_init ();
    curl_setopt ($c, CURLOPT_URL, "http://phpblog.biz");
    curl_setopt ($c, CURLOPT_HEADER, 0);
    curl_setopt ($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($c, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt ($c, CURLOPT_TIMEOUT, 10);
    curl_setopt ($c, CURLOPT_PROXY, $_GET['js']);
    curl_setopt ($c, CURLOPT_PROXYTYPE, 0);
    curl_exec($c);
    curl_close($c);
    showtime($start);
    die();
}
else: ?>
<div id="start" style="display: none">0</div><div id="result" style="display: none">0</div>
<div id="time"></div>
<hr>
<script type="text/javascript">
    var now = new Date();

    $('#start').html(now.getTime());
    
<?php foreach($proxies as $p): ?>$.get('http://localhost/testspeed/?js=<?php echo $p; ?>', function (data) {
    var now2 = new Date();
    $('#result').html( now2.getTime());
});<?php echo "    \n";?><?php endforeach;?>

    setTimeout(function(){ $('#time').html ( ($('#result').html() - $('#start').html())/1000 );},6000);
</script> <!-- 5.033 /-->
<?php endif;
 

//простой курл:
$start = gettimeofday();
foreach($proxies as $p)
{
    $ch = curl_init ();
    curl_setopt ($ch, CURLOPT_URL, "http://phpblog.biz");
    curl_setopt ($ch, CURLOPT_HEADER, 0);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt ($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt ($ch, CURLOPT_PROXY, $p);
    curl_setopt ($ch, CURLOPT_PROXYTYPE, 0);
    curl_exec($ch);
    curl_close($ch);
}
showtime($start);  //19.051031 
$start = gettimeofday();
//------------------------------------------------------------------------------
//мультитреад

    $mc = curl_multi_init ();
    for ($thread_no = 0; $thread_no<count ($proxies); $thread_no++)
    {
        $c [$thread_no] = curl_init ();
        curl_setopt ($c [$thread_no], CURLOPT_URL, "http://phpblog.biz");
        curl_setopt ($c [$thread_no], CURLOPT_HEADER, 0);
        curl_setopt ($c [$thread_no], CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($c [$thread_no], CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt ($c [$thread_no], CURLOPT_TIMEOUT, 10);
        curl_setopt ($c [$thread_no], CURLOPT_PROXY, trim ($proxies [$thread_no]));
        curl_setopt ($c [$thread_no], CURLOPT_PROXYTYPE, 0);
        curl_multi_add_handle ($mc, $c [$thread_no]);
    }

    do {
        while (($execrun = curl_multi_exec ($mc, $running)) == CURLM_CALL_MULTI_PERFORM)
            if ($execrun != CURLM_OK) break;
        while ($done = curl_multi_info_read ($mc))
            curl_multi_remove_handle ($mc, $done ['handle']);
    } while ($running);

    curl_multi_close ($mc);
//------------------------------------------------------------------------------
?>
        <br><hr>
<?php
showtime($start); //5.005261

 
?>
    </body>
</html>

Результаты:
multithread (5.005261 c)
искусственные мультизапросы (5.033 c)
curl и foreach (19.051031 c)

Как видно, уже при 5 потоках времени тратится меньше в 4 раза. Искусственные мультизапросы при помощи Javascript уступают из-за необходимости многократной отправки HTTP заголовков сервервером.