4

ファイルの一部をダウンロードするスクリプトを作成しようとしています。CURL と fread でテストを行うだけで、ストリーミング プロセス中の CURL は fread よりも遅いことがわかりました。なんで?ファイルをストリームするためにcurlを高速化する方法は? ストリーミング処理中に限られた時間を必要とするため、 fread 、 fopen を使用したくありません。

これが私のサンプルコードです。

$start = microtime(true);
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';
$response = fread($f, 3); echo $response.'<br>';

$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

fread / fopen わずか1.1秒

$start = microtime(true);
$curl = curl_init('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg');
curl_setopt($curl, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($curl, CURLOPT_RANGE, "0-2");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "3-5");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "6-8");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "9-11");
$response = curl_exec($curl);echo $response.'<br>';

curl_setopt($curl, CURLOPT_RANGE, "12-14");
$response = curl_exec($curl);echo $response.'<br>';
curl_close($curl);

$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

curl には約 2.5 秒かかりました。ファイルのより多くの部分をダウンロードするためにさらに一歩踏み出すと。curl はさらに遅くなります。

curl が遅いのはなぜですか? そしてそれはどのような解決策ですか?

4

5 に答える 5

3

HTTP 呼び出しのラウンドトリップを追加したため、常に遅くなります。すべての curl_exec は、単一の HTTP 要求です。

于 2013-10-28T08:41:01.810 に答える
2

あなたの質問は、多くの部分的なリクエストを持つこと、または同じリクエストの増分バッファリング読み取りについてです。

fopen/fread 実装は、単一の HTTP 要求を起動し、それを何度も少しずつ読み取ります。

一方、curl の実装では、1 ピースにつき 1 つのリクエストで、多数の HTTP リクエストが発生します (部分範囲リクエストを参照)。リンゴとオレンジを比較しています

公平を期すために、fopen/fread は次のようになります

$start = microtime(true);
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 3);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 6);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 9);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$f = fopen('http://news.softpedia.com/images/news2/Debian-Turns-15-2.jpeg','r');
fseek($f, 12);
$response = fread($f, 3); echo $response.'<br>';
fclose($f)
$stop = round(microtime(true) - $start, 5);
echo "{$stop}s";
exit();

更新:答えを書き直しました

于 2013-10-28T09:13:25.847 に答える
1

curl_getinfoを使用して、時間がかかっているものを確認できます。

遅いのは、curl ライブラリによる DNS ルックアップが原因である可能性があります。リクエスト URL にドメインの代わりに IP アドレスを使用してみましたか?

EDIT :または、 trueに設定してより長い値 (例: 1 時間) に設定CURLOPT_DNS_USE_GLOBAL_CACHEすることもできます。デフォルトでは 2 分です。CURLOPT_DNS_CACHE_TIMEOUT

ソース: http://php.net/manual/en/function.curl-setopt.php

于 2013-10-23T09:33:33.800 に答える
0

たとえば、次のように 300 秒のように、Keep-Alivefirst の前にヘッダーを設定してみてください。curl_exec

$headers = array("Keep-Alive: 300");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
于 2013-10-22T11:38:11.903 に答える