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

ext\curl\tests\bug45161.phpt test is absurdly slow on Windows #10753

Closed
mvorisek opened this issue Mar 2, 2023 · 20 comments
Closed

ext\curl\tests\bug45161.phpt test is absurdly slow on Windows #10753

mvorisek opened this issue Mar 2, 2023 · 20 comments

Comments

@mvorisek
Copy link
Contributor

mvorisek commented Mar 2, 2023

Description

I report this as a performance bug.

(209.652 s) Bug #45161 (Reusing a curl handle leaks memory) [D:\a\php-src\php-src\ext\curl\tests\bug45161.phpt]

CI: https://github.com/php/php-src/actions/runs/4308375002/jobs/7514584871#step:8:113

on Windows 1024 iterations - https://github.com/php/php-src/blob/master/ext/curl/tests/bug45161.phpt - takes > 200 seconds, on linux/MacOS it takes <1 second

there is probably something wrong with Windows code

maybe related with #10119

PHP Version

8.2 and master, x86 and x64

Operating System

Windows

@Jan-E
Copy link
Contributor

Jan-E commented Mar 4, 2023

PHP Version
8.2 and master, x86 and x64

The same happens on PHP 8.0.28 NTS x64

@mvorisek
Copy link
Contributor Author

mvorisek commented Apr 3, 2023

Can someone please look into this issue?

@iluuu1994
Copy link
Member

I don't have a Windows machine to test this. Is running it locally equally slow?

@Jan-E
Copy link
Contributor

Jan-E commented Apr 4, 2023

Yes. Running the tests for curl takes on my machine 250 seconds, almost entirely due to this single test.

@iluuu1994
Copy link
Member

@Jan-E Are the requests that slow? Can you debug the script to check which part causes it?

@Jan-E
Copy link
Contributor

Jan-E commented Apr 5, 2023

I debugged the script by adding milliseconds to the output. All tests were done with Curl 8.0.1.

$start = memory_get_usage() + 1024;
for($i = 0; $i < 1024; $i++) {                                                                                             
    curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc");
    curl_setopt($ch, CURLOPT_FILE, $fp);
    $stime = date_create()->format('Uv');
    echo $stime."\n";
    curl_exec($ch);
    $stime = date_create()->format('Uv');
    echo $stime."\n";
}

Of course the test failed with the extra output, but it told me that on my machine every curl_exec($ch) took about 210 milliseconds. Multiply this by 1024 and you end up with a test duration of 215 seconds.

Which raises the question: is the curl request slow or the server that the test script launches? The server listens on localhost on a random port, but as long as the script was running I could detect on which port and launch the same request from a DOS-prompt. Detecting the port:

$ netstat -anb | grep TIME_WAIT
....
  TCP    [::1]:60323            [::1]:60543            TIME_WAIT
  TCP    [::1]:60323            [::1]:60545            TIME_WAIT
  TCP    [::1]:60323            [::1]:60548            TIME_WAIT
  TCP    [::1]:60323            [::1]:60550            TIME_WAIT
  TCP    [::1]:60323            [::1]:60552            TIME_WAIT
  TCP    [::1]:60323            [::1]:60554            TIME_WAIT
  TCP    [::1]:60324            [::1]:60323            TIME_WAIT

Doing the same request with curl.exe:

$ ptime curl -o nul http://localhost:60323/get.inc

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>

===  curl -o nul http://localhost:60323/get.inc ===
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    25    0    25    0     0    113      0 --:--:-- --:--:-- --:--:--   113

Execution time: 0.281 s. A bit longer than the same request from within PHP.
wget.exe was quicker:

$ ptime wget http://localhost:60323/get.inc

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>

===  wget http://localhost:60323/get.inc ===
--2023-04-04 18:37:30--  http://localhost:60323/get.inc
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:60323... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'get.inc'

get.inc                    [ <=>                        ]      25  --.-KB/s    in 0s

2023-04-04 18:37:30 (394 KB/s) - 'get.inc' saved [25]

Execution time: 0.076 s, which amounts to about 27% of the time curl.exe took for it.

Conclusions: the test server on Windows is slow. but it seems that requesting http://localhost:60323/get.inc by means of Curl is causing a greater delay.

As a BTW: I am getting the same results for this test from PHP 7.3 onwards. The test in PHP 7.2 was skipped as 'Not for Windows'.

@iluuu1994
Copy link
Member

@Jan-E Thank you for your fantastic analysis! I'll compare the results to Linux. @adoy I reckon you don't have an explanation on why Curl on Windows is so slow?

@iluuu1994
Copy link
Member

On Linux the entire test with all 1024 iterations finishes in 0.15 seconds. I'm not sure what's going on here on Windows. This could also be an issue with cli-server itself on Windows.

@adoy
Copy link
Member

adoy commented Apr 6, 2023

@Jan-E Thank you for your fantastic analysis! I'll compare the results to Linux. @adoy I reckon you don't have an explanation on why Curl on Windows is so slow?

@iluuu1994 No. And I don't have a windows machine do test it. It looks like it's really a curl issue, we should probably report this upstream.

iluuu1994 added a commit that referenced this issue Apr 13, 2023
See GH-10753

The test is insanely slow on Windows and it's unclear why. It might be a curl
issue.
@M1ke
Copy link

M1ke commented Dec 12, 2023

I can confirm this issue happens on Linux too; we built a PHP8.1 server on the latest build of Ubuntu 22.04 LTS which has openssl 3; web response times were 25-50% slower across thousands of endpoints (most of which are database-backed so we generally assume any slowness comes from the database). Tracked it down to our use of AWS DDB for session storage, and within that the curl prerequest time was double or triple the length of time on the same server with Ubuntu 20.04 LTS (using openssl 1.1)

dark blue - server running 22.04, php8.1, openssl 3
other lines - 20.04, php7.4, openssl 1.1
Selection_001

light blue - server running 20.04, php8.1, openssl 1.1
other lines - 20.04, php7.4, openssl 1.1
Selection_002

So we can see here that the same build, code running php8.1 looked bad compared to 7.4, until we downgraded openssl where we see performance of 8.1 on the lower end of the average 7.4 performance, and definitely no distinct increase. Openssl 3 definitely causing these issues (I imagine other people may report curl issues as they migrate php versions and in the process accidentally bump their openssl version)

@GrahamCampbell
Copy link
Contributor

OpenSSL 3.2 has some changes which may improve things. Is anyone able to compare 3.0 vs 3.2?

@cmb69
Copy link
Member

cmb69 commented Jul 17, 2024

I faintly remember a super slow test on Windows after some cURL update; I don't remember exactly which test it has been, but the issue might have been related to curl/curl#9296 (so that would have been cURL 7.85.0).

Anyhow, bug45161.phpt (without that SKIPIF section) runs pretty fast for me (PHP-8.2, cURL 8.7.1), but is somewhat slower (~7s) on PHP-8.1, cURL 7.77.0. When I replace the $host assignment line at the top of the --FILE-- section with
$host = str_replace('localhost', curl_cli_server_start(), '127.0.0.1');, the test is as fast as on PHP-8.2 (~2s).

@mvorisek
Copy link
Contributor Author

This issue is easily verifyable using linux/Windows Github Actions CI based on the description:

on Windows 1024 iterations - https://github.com/php/php-src/blob/master/ext/curl/tests/bug45161.phpt - takes > 200 seconds, on linux/MacOS it takes <1 second

of course, with 4b22c3e reverted

@cmb69
Copy link
Member

cmb69 commented Jul 17, 2024

@mvorisek, it is not listed in the slow tests section for a recent test build. Either the test has not been executed, or it isn't that slow anymore.

@mvorisek
Copy link
Contributor Author

So let's land cmb69@1bd111e and close this issue.

@cmb69
Copy link
Member

cmb69 commented Jul 17, 2024

Let's wait a bit, please. I want to see how long the test took.

@Jan-E
Copy link
Contributor

Jan-E commented Jul 18, 2024

On my system with PHP 8.4.0 Alpha 2 NTS x64:

=====================================================================
PHP         : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\php.exe
PHP_SAPI    : cli
PHP_VERSION : 8.4.0alpha2
ZEND_VERSION: 4.4.0-dev
PHP_OS      : WINNT - Windows NT X220I7 10.0 build 19045 (Windows 10) AMD64
INI actual  : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\php.ini
More .INIs  :
---------------------------------------------------------------------
PHP         : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\php-cgi.exe
PHP_SAPI    : cgi-fcgi
PHP_VERSION : 8.4.0alpha2
ZEND_VERSION: 4.4.0-dev
PHP_OS      : WINNT - Windows NT X220I7 10.0 build 19045 (Windows 10) AMD64
INI actual  : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\php.ini
More .INIs  :
---------------------------------------------------------------------
---------------------------------------------------------------------
PHP         : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\phpdbg.exe
PHP_SAPI    : phpdbg
PHP_VERSION : 8.4.0alpha2
ZEND_VERSION: 4.4.0-dev
PHP_OS      : WINNT - Windows NT X220I7 10.0 build 19045 (Windows 10) AMD64
INI actual  : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2\php.ini
More .INIs  :
---------------------------------------------------------------------
CWD         : N:\php-sdk\php84dev\x64\Release\php-8.4.0alpha2
Extra dirs  :
VALGRIND    : Not used
=====================================================================
Running selected tests.
PASS Bug #45161 (Reusing a curl handle leaks memory) [N:\php-sdk\php84dev\ext\curl\tests\bug45161.phpt]
=====================================================================
Number of tests :     1                 1
Tests skipped   :     0 (  0.0%) --------
Tests warned    :     0 (  0.0%) (  0.0%)
Tests failed    :     0 (  0.0%) (  0.0%)
Tests passed    :     1 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken      : 1.486 seconds
=====================================================================

1.5 seconds is not insanely long, given that all curl tests take 29 seconds on the same system.

@Jan-E
Copy link
Contributor

Jan-E commented Jul 18, 2024

@cmb69
Copy link
Member

cmb69 commented Jul 18, 2024

So we might assume that this has been "fixed in third party library" (unless someone is willing to verify this exactly).

@Jan-E
Copy link
Contributor

Jan-E commented Jul 18, 2024

I am not going to do the analysis in #10753 (comment) once again, so I guess that would be right. Building PHP 8.2.22RC1 TS x64 right now to verify that the test takes about 1 second on my system as well. I will edit the test time into this comment once it has been done.

Edit No fractions of seconds when running the 8.2 tests. 1 or 2 seconds for bug45161 out of a total of 34/35 for all curl tests.

@cmb69 cmb69 closed this as completed in 355baf9 Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants