Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guzzle is super slow comparing to file_get_content #395

Closed
scottzhang opened this issue Aug 7, 2013 · 9 comments
Closed

Guzzle is super slow comparing to file_get_content #395

scottzhang opened this issue Aug 7, 2013 · 9 comments

Comments

@scottzhang
Copy link

I get to know guzzle when I integrate an oauthclient which use guzzle by default.
So when I don't use oauthclient, I still keep guzzle for http request from php.

We are using GuzzleClient to request our oauth protected api. Usually when we visit our api url directly from browser, the response/full load time is about 40ms, we measured this by firebug.

But when we get same url from guzzleClient using GET, it always take ~100-120ms. It is really unacceptable. We try to use file_get_content, it needs ~40-50ms.

So we follow the code into GuzzleClient, before jump into its 'group->send' call, I use php microtime() to track, it already consumed ~10-20ms for all these addon wrapper code, and its "$group->send()" take about ~90ms. Still slow.

I know guzzle added many code for some advanced features before a real send but its speed is really slow.

I am trying to test phpcurl or Http_Request2 which only provide a pure send interface to overcome the performance issue.

@mtdowling
Copy link
Member

Guzzle isn't slow (I've measured requests with Amazon DynamoDB that take around 4ms to complete), but it's possible that something in your stack is causing it to perform badly.

  1. What version of PHP/curl are you using and on what platform?
  2. Can you provide the output of cURL's verbose output please? $client->getConfig()->set('curl.options', array(CURLOPT_VERBOSE => true));. Is an Expect header being added? Are you being redirected?
  3. Is the API and the test you are performing on the same box or over a very low latency connection?

@scottzhang
Copy link
Author

Hi. Thanks for you reply.

I am pretty sure guzzle runs slow on my computer. The api website and test website are running on same computer. I tried file_get_content has same speed as browser, and Http_Request2 which replies on curl too doing fast. Only guzzle works bad.
But I will try your code, update here soon.

@mtdowling
Copy link
Member

It sounds like a system tuning issue.

Do you have xdebug enabled? Are you using an op code cache?

On Aug 6, 2013, at 11:11 PM, scottzhang notifications@github.com wrote:

Hi. Thanks for you reply.

I am pretty sure guzzle runs slow on my computer. The api website and test website are running on same computer. I tried file_get_content has same speed as browser, and Http_Request2 which replies on curl too doing fast. Only guzzle works bad.
But I will try your code, update here soon.


Reply to this email directly or view it on GitHub.

@scottzhang
Copy link
Author

Hi. Here is the test. first is code:

try
{
$client = new GuzzleClient();
$client->getConfig()->set('curl.options', array(CURLOPT_VERBOSE => true));
echo " guzzle start ".microtime();
$request = $client->get('http://api.weidan.com/categories');
// $request = $client->get($uri,$headers,$params);
$response = $request->send();
echo " guzzle end ".microtime();
}
catch (\Guzzle\Http\Exception\BadResponseException $e)
{
$raw_response = explode("\n", $e->getResponse());
throw new IDPException(end($raw_response));
}
echo "
";
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2('http://api.weidan.com/categories', HTTP_Request2::METHOD_GET);
try {
echo "http_request2 start ".microtime();
$response = $request->send();
echo " http_request2 end ".microtime();
} catch (HTTP_Request2_Exception $e) {
}
echo "
file_get_contents ";
echo microtime();
file_get_contents('http://api.weidan.com/categories');
echo " end ".microtime();

here is the test result for 4 runs
#1:
guzzle start 0.59919000 1375857134 guzzle end 0.82729000 1375857134
http_request2 start 0.83789400 1375857134 http_request2 end 0.95513200 1375857134
file_get_contents 0.95514600 1375857134 end 0.07018400 1375857135

#2:
guzzle start 0.20744200 1375857145 guzzle end 0.40526400 1375857145
http_request2 start 0.41455200 1375857145 http_request2 end 0.52236900 1375857145
file_get_contents 0.52237800 1375857145 end 0.62295500 1375857145

#3:
guzzle start 0.02246900 1375857153 guzzle end 0.19694000 1375857153
http_request2 start 0.20564100 1375857153 http_request2 end 0.30827200 1375857153
file_get_contents 0.30828800 1375857153 end 0.41158900 1375857153

#4:
guzzle start 0.16789400 1375857166 guzzle end 0.36963500 1375857166
http_request2 start 0.37839100 1375857166 http_request2 end 0.48142500 1375857166
file_get_contents 0.48145300 1375857166 end 0.57908300 1375857166

The "http://api.weidan.com/categories' is a webpage runs locally does nothing. We just request it and see the response time for benchmark.
You can see from above result, the file_get_contents is fast. HttpRequest add a few time cost. But guzzle usually take 90% more time.

I don't know what effect "$client->getConfig()->set('curl.options', array(CURLOPT_VERBOSE => true));" brings on. But on our test, nothing happens.

Please check.
Thanks.

@mtdowling
Copy link
Member

That option outputs verbose curl information. Check your apache logs if this is running with mod_php or something. You need to see this information to troubleshoot.

Perf tests with Xdebug enabled are worthless. Be sure it's disabled. Also ensure you're using an opcode cache.

If the API runs locally, then you might need to disable nagle's algorithm by setting the CURLOPT_TCP_NODELAY option just like how the verbose option was set.

What version of Guzzle, PHP, Curl, etc are you using?

On Aug 6, 2013, at 11:35 PM, scottzhang notifications@github.com wrote:

Hi. Here is the test. first is code:

try
{
$client = new GuzzleClient();
$client->getConfig()->set('curl.options', array(CURLOPT_VERBOSE => true));
echo " guzzle start ".microtime();
$request = $client->get('http://api.weidan.com/categories');
// $request = $client->get($uri,$headers,$params);
$response = $request->send();
echo " guzzle end ".microtime();
}
catch (\Guzzle\Http\Exception\BadResponseException $e)
{
$raw_response = explode("\n", $e->getResponse());
throw new IDPException(end($raw_response));
}
echo "
";
require_once 'HTTP/Request2.php';

$request = new HTTP_Request2('http://api.weidan.com/categories', HTTP_Request2::METHOD_GET);
try {
echo "http_request2 start ".microtime();
$response = $request->send();
echo " http_request2 end ".microtime();
} catch (HTTP_Request2_Exception $e) {
}

echo "
file_get_contents ";
echo microtime();
file_get_contents('http://api.weidan.com/categories');
echo " end ".microtime();

here is the test result for 4 runs
#1:
guzzle start 0.59919000 1375857134 guzzle end 0.82729000 1375857134
http_request2 start 0.83789400 1375857134 http_request2 end 0.95513200 1375857134
file_get_contents 0.95514600 1375857134 end 0.07018400 1375857135

#2:
guzzle start 0.20744200 1375857145 guzzle end 0.40526400 1375857145
http_request2 start 0.41455200 1375857145 http_request2 end 0.52236900 1375857145
file_get_contents 0.52237800 1375857145 end 0.62295500 1375857145

#3:
guzzle start 0.02246900 1375857153 guzzle end 0.19694000 1375857153
http_request2 start 0.20564100 1375857153 http_request2 end 0.30827200 1375857153
file_get_contents 0.30828800 1375857153 end 0.41158900 1375857153

#4:
guzzle start 0.16789400 1375857166 guzzle end 0.36963500 1375857166
http_request2 start 0.37839100 1375857166 http_request2 end 0.48142500 1375857166
file_get_contents 0.48145300 1375857166 end 0.57908300 1375857166

The "http://api.weidan.com/categories' is a webpage runs locally does nothing. We just request it and see the response time for benchmark.
You can see from above result, the file_get_contents is fast. HttpRequest add a few time cost. But guzzle usually take 90% more time.

I don't know what effect "$client->getConfig()->set('curl.options', array(CURLOPT_VERBOSE => true));" brings on. But on our test, nothing happens.

Please check.
Thanks.


Reply to this email directly or view it on GitHub.

@scottzhang
Copy link
Author

Hi. We are using Guzzle 3.7, the latest version get by composer. PHP version is 5.4.7. We are using Xampp as develop server. the CURL is integrated with xampp by default, curl version is 7.24.0 . Xampp is 3.1.0 Beta 6.

I think from the above tests we can tell, basically the web request time should be nearly same. The problem is guzzle and httprequest add many extra code to wrap the original api. HttpRequest2 runs on curl too. But HttpRequest2's performance is better because it is light weight than Guzzle. Guzzle add many code before really send the request, that's why it runs slower. As all our test runs in same function, they are using same server, curl. I think the version of PHP,curl has no impact for these tests.

Regards

@scottzhang
Copy link
Author

Hi.
When I first submit a ticket, I don't see the reason why it is slow. I
only compare it with file_get_content and see it is slow. For that point,
as guzzle provides more features than that simple file_get_content, I am
not sure is that worth the slow down. I left message in my ticket say we
will test curl and HttpRequest2.
We have no interesting in tuning server configuration, we just use. I
don't enable xdebug, don't know what is op cache. And then after the
testing, we found that without any extra tuning, HttpRequest2 works much
faster than guzzle so we now switch our code from guzzle to HttpRequest2.
So yes. I will close this.

On Wed, Aug 7, 2013 at 3:46 PM, Ben Davies notifications@github.com wrote:

Why are you raising a request for support if you think you already know
the answer.
Making blind assertions (Guzzle add many code before really send the
request) which you can't possible backup are of no help to anyone.

Why not actually accept the support offered, which is very forthcoming,
and take the steps you've been asked to take?
Either provide the CURL debug information requested, or close the ticket.
After all, you've already worked it all out.


Reply to this email directly or view it on GitHubhttps://github.com//issues/395#issuecomment-22235056
.

@ghost
Copy link

ghost commented Apr 25, 2017

slow guzzle depends, but keep attention to your environment! we had the same issue with a slow guzzle/6.2.1 and the problem was a special curl/7.29 version which caused the super slow performance, update the curl version was the solution

@clevercodenl
Copy link

@nczepa I think I might be having the same problem. To which curl version did you update it to ? Is there a list of specific curl versions that are not recommended to use with specific guzzle versions I can look at somewhere ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants