Dear All ... I'm not sure where to start with this. Basically I have been running 7.2 64 bit on IIS 10, seemingly no problems.
Most scripts seemed to be generally running fine, but there seemed to be some speed bumps which didn't make sense. I did some profiling, and found that *all* the slow down came from one place only, which is the . string concat.
The slow down was very significant (didn't notice because for most runs where it wasn't required much). However, after doing some investigating, I found that it was at least 100x slower than using ob_start() with echo (a PHP hack ...), instead of concatenating.
It cannot be that . concat is that much slower than echo and collecting the content. Other benchmarks show echo to be on 10% faster than . concat, not 10,000% faster!
Everywhere I search, I don't see this problem from others with PHP, and generally stated . concat should perform well. However, that's not the case here. I therefore conclude it might be a peculiarity with the Windows implementation. I don't have any others
to easily test.
Thanks for your posting, would you please share a snippet of your script that you are facing the performance issue? IIS itself doesn't execute PHP script directly and FastCGI module takes over PHP execution, therefore it shouldn't be an IIS issue.
Regards
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue.
Thanks Elendil ... yes I ran some helpful benchmarks using this code ... and the performance difference with buffer/echo is about x350 faster then standard string concatenation. This is with $n = 300000. Interesting, it is only with $n > 2000 that you start
to see a performance gap. I think something is limiting string size memory in PHP to around this and needs to swap somewhere / reallocate to new memory? Just a thought.
Windows Server 2016 / IIS 10 / PHP 7.2 64x
output from benchmark
buffer/echo concatenation 0.020689964294434s Standard concatenation 7.7018699645996s 372x difference
I tried adding php://memory buffer method instead of ob_start() buffer ... (less of a hack). And I found it was almost 2x faster even than ob_start! So the difference in performance between this and standard . concatenation is
x600 slower than this method with $n = 300000!! I thought the sql query would be the bottleneck, this is the bottlneck by a really big margin ... ?
In general if you look for "exactly the same performance" then you come to a wrong place.
Lex Li
Affordable IIS Consulting Services at https://support.lextudio.com/services/consulting.html
---------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
Thanks very much for the diagram, that is helpful.
First, it's not crashing, it works. The problem is that there is a huge performance discrepancy between the Window IIS string concat operator and other implementations. This would be fine, except string concat is mission critical for most PHP implementations
as a SQL processor.
And second, the performance difference is huge ... order of 35,000% (yes ... not a typo). If it were "only" 200% / 2x slower ... not problem.
I'm fairly sure it's not in the PHP implementation ... although it might be. No other implementation seems to have this issue ... and therefore I have found no were else to help on this.
It's obviously something specific to how memory or performance limitations in Windows has caused the string concat function to be extremely slow for larger strings.
I'm pretty sure this is a central issue to anyone using PHP on IIS Windows since I'm sure they will be at some point concatenating longer strings for SQL queries ...?
If there is any coding input from anyone in the Windows/IIS/PHP community that would be really great!
I'm not an expert of PHP but I can provide my advise
the echo just flushes buffer to the output stream, all memory it uses is the buffer, so no memory leak would be there
on the other hand .concat, I searched this in bing and it seems in PHP string is mutable, just think what it will happen while you are calling a .concat function under the surface(of course that is based on my understanding of what most language would do)
1. Check if the buffer that assigned to current string is long enough to store the appended content (you memory allocated to the current string is 1k in serial, 0.8k is used)
2. If not, Find a piece of memory that is long enough to store the new string and double the buffer size(you want to .concat another 0.5k size string to the current string, while only 0.2k is left, so system looks for another piece of memory whose size is
2K to store your new string)
3. Copy the current string to the new memory address
4. during this phase, if memory limitation was met, some of the data would be stored in Virtual Memory, which will result to missing page interruption, and finally goes to an IO operation
So basically the .concat would leads to high memory cost and a potential of memory fragmentation while in echo you are just using buffer size memory and no more memory was allocated
I would suggest that you can do a quick monitor of your php applicaiton against IO and Memory allocation by opening
Task Manager, click Performance Tab, at the bottom, click the
Open Resource Monitor, than find your PHP process and track the IO and Memory data to find out the bottleneck
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue.
The problem is that there is a huge performance discrepancy between the Window IIS string concat operator and other implementations
If the issue is something inside php-cgi.exe, then IIS is not in the picture, and you should chase whoever backs PHP on Windows (the original developers behind that open source project). It would be either possible or impossible to solve such issues. For
example, ASP.NET Core on Linux does lost some performance compared to its Windows counterpart (but not too far apart).
There would be little help from Windows/IIS, as you won't expect any change to make there to speed up PHP.
BTW, what antivirus software are you using? Consider most Linux users won't install such, you might temporarily disable antivirus on Windows and test again to eliminate its impact.
Lex Li
Affordable IIS Consulting Services at https://support.lextudio.com/services/consulting.html
---------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
Just to close this thread, after the discussion. The issue remains. I implemented my own custom PHP stringbuilder, using php://mem as a buffer. Works incredibly fast (I think it's the fastest out of all approaches) and has no size limit other than physical
memory.
7 Posts
PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 02:03 AM|niceblue|LINK
Dear All ... I'm not sure where to start with this. Basically I have been running 7.2 64 bit on IIS 10, seemingly no problems.
Most scripts seemed to be generally running fine, but there seemed to be some speed bumps which didn't make sense. I did some profiling, and found that *all* the slow down came from one place only, which is the . string concat.
The slow down was very significant (didn't notice because for most runs where it wasn't required much). However, after doing some investigating, I found that it was at least 100x slower than using ob_start() with echo (a PHP hack ...), instead of concatenating. It cannot be that . concat is that much slower than echo and collecting the content. Other benchmarks show echo to be on 10% faster than . concat, not 10,000% faster!
Everywhere I search, I don't see this problem from others with PHP, and generally stated . concat should perform well. However, that's not the case here. I therefore conclude it might be a peculiarity with the Windows implementation. I don't have any others to easily test.
Every other aspect of PHP on IIS works well.
Any help on this would be greatly appreciated!
11 Posts
Microsoft
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 07:06 AM|Elendil Zheng|LINK
Hi niceblue,
Thanks for your posting, would you please share a snippet of your script that you are facing the performance issue? IIS itself doesn't execute PHP script directly and FastCGI module takes over PHP execution, therefore it shouldn't be an IIS issue.
Regards
Please remember to "Mark as Answer" the responses that resolved your issue.
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 10:57 AM|niceblue|LINK
Thanks Elendil ... yes I ran some helpful benchmarks using this code ... and the performance difference with buffer/echo is about x350 faster then standard string concatenation. This is with $n = 300000. Interesting, it is only with $n > 2000 that you start to see a performance gap. I think something is limiting string size memory in PHP to around this and needs to swap somewhere / reallocate to new memory? Just a thought.
Windows Server 2016 / IIS 10 / PHP 7.2 64x
output from benchmark
buffer/echo concatenation 0.020689964294434s
Standard concatenation 7.7018699645996s
372x difference
code
$n = 300000;
$output = "";
$timer = microtime(true);
ob_start();
for ($i = 0; $i < $n; $i ++)
{
echo "(" , 123 , "),";
}
$output = ob_get_clean();
$buffertime = microtime(true) - $timer;
echo "buffer/echo concatenation ", $buffertime, "s<br>";
$output = "";
$timer = microtime(true);
for ($i = 0; $i < $n; $i ++)
{
$output = $output . "(" . 123 . "),";
}
$concatenationtime = microtime(true) - $timer;
echo "Standard concatenation ", $concatenationtime, "s<br>";
echo (int)($concatenationtime / $buffertime), "x difference";
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 11:31 AM|niceblue|LINK
I tried installing the new PHP 7.3 (from Web PI) and running the same benchmark ... the performance difference is even bigger (almost x500).
Admittedly don't have wincache installed on 7.3, but did have on 7.2.
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 12:01 PM|niceblue|LINK
bit more testing ... with $n = 300 the time for buffer/echo and string concatenation are the same.
so if $n < 300 then string concatenation is faster
after $n > 300 then buffer/echo is faster, and the difference grows exponentially with increasing $n
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 12:36 PM|niceblue|LINK
And more work ...
I tried adding php://memory buffer method instead of ob_start() buffer ... (less of a hack). And I found it was almost 2x faster even than ob_start! So the difference in performance between this and standard . concatenation is x600 slower than this method with $n = 300000!! I thought the sql query would be the bottleneck, this is the bottlneck by a really big margin ... ?
php://memory buffer code
$timer = microtime(true);
$handle = fopen("php://memory", "r+");
for ($i = 0; $i < $n; $i++)
{
fwrite($handle, "(" . 123 . "),");
}
fseek($handle, 0);
$output = fread($handle, 1000000);
fclose($handle);
$fwritetime = microtime(true) - $timer;
echo "php://memory concatenation ", $fwritetime, "s<br>";
echo ($fwritetime / $buffertime), "x difference<br>";
8960 Posts
MVP
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 02:47 PM|lextm|LINK
Keep in mind that different implementations matter (Linux vs. Windows).
You might also learn the architecture, https://blog.lextudio.com/who-should-be-contacted-for-php-on-iis-issues-c80b90bd365
In general if you look for "exactly the same performance" then you come to a wrong place.
Affordable IIS Consulting Services at https://support.lextudio.com/services/consulting.html
---------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 12, 2019 04:19 PM|niceblue|LINK
Thanks very much for the diagram, that is helpful.
First, it's not crashing, it works. The problem is that there is a huge performance discrepancy between the Window IIS string concat operator and other implementations. This would be fine, except string concat is mission critical for most PHP implementations as a SQL processor.
And second, the performance difference is huge ... order of 35,000% (yes ... not a typo). If it were "only" 200% / 2x slower ... not problem.
I'm fairly sure it's not in the PHP implementation ... although it might be. No other implementation seems to have this issue ... and therefore I have found no were else to help on this.
It's obviously something specific to how memory or performance limitations in Windows has caused the string concat function to be extremely slow for larger strings.
I'm pretty sure this is a central issue to anyone using PHP on IIS Windows since I'm sure they will be at some point concatenating longer strings for SQL queries ...?
If there is any coding input from anyone in the Windows/IIS/PHP community that would be really great!
11 Posts
Microsoft
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 13, 2019 02:28 AM|Elendil Zheng|LINK
Hi niceblue
I'm not an expert of PHP but I can provide my advise
the echo just flushes buffer to the output stream, all memory it uses is the buffer, so no memory leak would be there
on the other hand .concat, I searched this in bing and it seems in PHP string is mutable, just think what it will happen while you are calling a .concat function under the surface(of course that is based on my understanding of what most language would do)
1. Check if the buffer that assigned to current string is long enough to store the appended content (you memory allocated to the current string is 1k in serial, 0.8k is used)
2. If not, Find a piece of memory that is long enough to store the new string and double the buffer size(you want to .concat another 0.5k size string to the current string, while only 0.2k is left, so system looks for another piece of memory whose size is 2K to store your new string)
3. Copy the current string to the new memory address
4. during this phase, if memory limitation was met, some of the data would be stored in Virtual Memory, which will result to missing page interruption, and finally goes to an IO operation
So basically the .concat would leads to high memory cost and a potential of memory fragmentation while in echo you are just using buffer size memory and no more memory was allocated
I would suggest that you can do a quick monitor of your php applicaiton against IO and Memory allocation by opening Task Manager, click Performance Tab, at the bottom, click the Open Resource Monitor, than find your PHP process and track the IO and Memory data to find out the bottleneck
Please remember to "Mark as Answer" the responses that resolved your issue.
8960 Posts
MVP
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Mar 13, 2019 02:31 AM|lextm|LINK
If the issue is something inside php-cgi.exe, then IIS is not in the picture, and you should chase whoever backs PHP on Windows (the original developers behind that open source project). It would be either possible or impossible to solve such issues. For example, ASP.NET Core on Linux does lost some performance compared to its Windows counterpart (but not too far apart).
There would be little help from Windows/IIS, as you won't expect any change to make there to speed up PHP.
BTW, what antivirus software are you using? Consider most Linux users won't install such, you might temporarily disable antivirus on Windows and test again to eliminate its impact.
Affordable IIS Consulting Services at https://support.lextudio.com/services/consulting.html
---------------------------
This posting is provided "AS IS" with no warranties, and confers no rights.
7 Posts
Re: PHP 7.2 on IIS extremely slooow . string concat, but everything else works great??!
Aug 12, 2020 07:34 PM|niceblue|LINK
Just to close this thread, after the discussion. The issue remains. I implemented my own custom PHP stringbuilder, using php://mem as a buffer. Works incredibly fast (I think it's the fastest out of all approaches) and has no size limit other than physical memory.