[PHP-DEV] Poor date() performance (v 5.4.9) [PATCH]
I am migrating from 4.4.9 to some new servers I built out, and wrote a benchmark suite that is testing many individual aspects of PHP so I could see what sort of performance benefits I might see not only from the new server, but moving off my custom forked 4.4.9 branch. Here's a snippet of some of the comparisons: (sorry for the poor formatting) -- each test is run using 1 million loops. 4.4.9 on old machine vs 5.4.9 on new machine: for : 0.213 sec for : 0.019 sec while : 0.145 sec while : 0.014 sec if else : 0.449 sec if else : 0.069 sec switch : 0.547 sec switch : 0.087 sec Ternary : 0.418 sec Ternary : 0.066 sec str_replace : 1.043 sec str_replace : 0.421 sec preg_replace: 3.627 sec preg_replace: 1.678 sec preg_match : 1.250 sec preg_match : 0.509 sec As you can see, the new machine is considerably faster, and there are no major issues with wanting to switch... until I get to the date functions I make frequent use of: date: 1.856 sec date: 2.111 sec strtotime : 2.963 sec strtotime : 3.133 sec and just to test (though I don't currently use it): strftime: 2.679 sec strftime: 1.764 sec The former two actually are slower on the new box and newer version of php, when everything else is 2 to 200x faster. Relevant code to the functions: (tested with and without the $now parameter -- which makes no perceptible difference) date('F j, Y, g:i a', $now); strftime('%B %e, %Y, %l:%M %P', $now); This type of formatting is pretty common. I started digging into the source code, and found an obvious place where there was a performance issue: timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); is being called every time, even though it's only used in two rather obscure cases, and ones that are probably very uncommon in actual practice. So, to test, I created a is set type variable, and moved the function call into each case, with a condition checking if it was already populated, if not, call the function to populate isoweek and isoyear, then resume as before. (Patch will be attached as a file) I then recompiled and reran my benchmark and here is the result: date: 1.763 sec Which is a performance increase of nearly 20%. My patch was thrown together rather quickly to just do a quick test, so it may warrant some tweaking before being applied to any branches. I plan to continue digging, as I feel that I should be able to continue to improve the performance of these functions further. The rest will be a little less obvious, is there is much more cross functionality issues to contend with to ensure nothing is broken. Side note- I attempted the same concept with not setting the timezone information if those flags were not used in the switch (which they aren't in anything I use), but it didn't appear to have any noticeable performance increase. My next step is to start tracing through actual execution and see if I can't find any other obvious issues. My initial thoughts are that it may be faster to try and cache some of this (for fcgi purposes), or even have a compile time option to allow a build to use old 4.4.9 functionality that uses localtime_r() and actually trusts that the server has the right information set. Thanks in advance for looking at this with me! -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Poor date() performance (v 5.4.9) [PATCH]
Hi, 2012/12/1 Paul Taulborg njag...@gmail.com I am migrating from 4.4.9 to some new servers I built out, and wrote a benchmark suite that is testing many individual aspects of PHP so I could see what sort of performance benefits I might see not only from the new server, but moving off my custom forked 4.4.9 branch. Here's a snippet of some of the comparisons: (sorry for the poor formatting) -- each test is run using 1 million loops. 4.4.9 on old machine vs 5.4.9 on new machine: for : 0.213 sec for : 0.019 sec while : 0.145 sec while : 0.014 sec if else : 0.449 sec if else : 0.069 sec switch : 0.547 sec switch : 0.087 sec Ternary : 0.418 sec Ternary : 0.066 sec str_replace : 1.043 sec str_replace : 0.421 sec preg_replace: 3.627 sec preg_replace: 1.678 sec preg_match : 1.250 sec preg_match : 0.509 sec As you can see, the new machine is considerably faster, and there are no major issues with wanting to switch... until I get to the date functions I make frequent use of: date: 1.856 sec date: 2.111 sec strtotime : 2.963 sec strtotime : 3.133 sec and just to test (though I don't currently use it): strftime: 2.679 sec strftime: 1.764 sec The former two actually are slower on the new box and newer version of php, when everything else is 2 to 200x faster. Relevant code to the functions: (tested with and without the $now parameter -- which makes no perceptible difference) date('F j, Y, g:i a', $now); strftime('%B %e, %Y, %l:%M %P', $now); This type of formatting is pretty common. I started digging into the source code, and found an obvious place where there was a performance issue: timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); is being called every time, even though it's only used in two rather obscure cases, and ones that are probably very uncommon in actual practice. So, to test, I created a is set type variable, and moved the function call into each case, with a condition checking if it was already populated, if not, call the function to populate isoweek and isoyear, then resume as before. (Patch will be attached as a file) I then recompiled and reran my benchmark and here is the result: date: 1.763 sec Which is a performance increase of nearly 20%. My patch was thrown together rather quickly to just do a quick test, so it may warrant some tweaking before being applied to any branches. I plan to continue digging, as I feel that I should be able to continue to improve the performance of these functions further. The rest will be a little less obvious, is there is much more cross functionality issues to contend with to ensure nothing is broken. Side note- I attempted the same concept with not setting the timezone information if those flags were not used in the switch (which they aren't in anything I use), but it didn't appear to have any noticeable performance increase. My next step is to start tracing through actual execution and see if I can't find any other obvious issues. My initial thoughts are that it may be faster to try and cache some of this (for fcgi purposes), or even have a compile time option to allow a build to use old 4.4.9 functionality that uses localtime_r() and actually trusts that the server has the right information set. Thanks in advance for looking at this with me! As far I remember, the patch must be in a .txt extension to be sent to the list. Thanks. -- Regards, Felipe Pena
[PHP-DEV] Re: Poor date() performance (v 5.4.9) [PATCH]
My apologies, pasting the patch in directly: --- php-5.4.9_orig/ext/date/php_date.c 2012-11-20 23:12:20.0 -0600 +++ php-5.4.9/ext/date/php_date.c 2012-12-01 05:38:22.136264276 -0600 @@ -948,6 +948,7 @@ timelib_time_offset *offset = NULL; timelib_sll isoweek, isoyear; int rfc_colon; + char weekYearSet = 0; if (!format_len) { return estrdup(); @@ -974,7 +975,6 @@ offset = timelib_get_time_zone_info(t-sse, t-tz_info); } } - timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); for (i = 0; i format_len; i++) { rfc_colon = 0; @@ -990,8 +990,12 @@ case 'z': length = slprintf(buffer, 32, %d, (int) timelib_day_of_year(t-y, t-m, t-d)); break; /* week */ - case 'W': length = slprintf(buffer, 32, %02d, (int) isoweek); break; /* iso weeknr */ - case 'o': length = slprintf(buffer, 32, %d, (int) isoyear); break; /* iso year */ + case 'W': + if(!weekYearSet) { timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); weekYearSet = 1; } + length = slprintf(buffer, 32, %02d, (int) isoweek); break; /* iso weeknr */ + case 'o': + if(!weekYearSet) { timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); weekYearSet = 1; } + length = slprintf(buffer, 32, %d, (int) isoyear); break; /* iso year */ /* month */ case 'F': length = slprintf(buffer, 32, %s, mon_full_names[t-m - 1]); break; -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: Poor date() performance (v 5.4.9) [PATCH]
--- php-5.4.9_orig/ext/date/php_date.c 2012-11-20 23:12:20.0 -0600 +++ php-5.4.9/ext/date/php_date.c 2012-12-01 05:38:22.136264276 -0600 @@ -948,6 +948,7 @@ timelib_time_offset *offset = NULL; timelib_sll isoweek, isoyear; int rfc_colon; + char weekYearSet = 0; if (!format_len) { return estrdup(); @@ -974,7 +975,6 @@ offset = timelib_get_time_zone_info(t-sse, t-tz_info); } } - timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); for (i = 0; i format_len; i++) { rfc_colon = 0; @@ -990,8 +990,12 @@ case 'z': length = slprintf(buffer, 32, %d, (int) timelib_day_of_year(t-y, t-m, t-d)); break; /* week */ - case 'W': length = slprintf(buffer, 32, %02d, (int) isoweek); break; /* iso weeknr */ - case 'o': length = slprintf(buffer, 32, %d, (int) isoyear); break; /* iso year */ + case 'W': + if(!weekYearSet) { timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); weekYearSet = 1; } + length = slprintf(buffer, 32, %02d, (int) isoweek); break; /* iso weeknr */ + case 'o': + if(!weekYearSet) { timelib_isoweek_from_date(t-y, t-m, t-d, isoweek, isoyear); weekYearSet = 1; } + length = slprintf(buffer, 32, %d, (int) isoyear); break; /* iso year */ /* month */ case 'F': length = slprintf(buffer, 32, %s, mon_full_names[t-m - 1]); break; -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Poor date() performance (v 5.4.9) [PATCH]
On 12/01/2012 10:21 AM, Paul Taulborg wrote: [php_date.c patch] Thanks for the patch. To ensure it isn't lost, can you open a bug at https://bugs.php.net/ and attach it? And/or submit a pull request at https://github.com/php/php-src Regards, Chris -- christopher.jo...@oracle.com http://twitter.com/ghrd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Poor date() performance (v 5.4.9) [PATCH]
Submitted here: https://bugs.php.net/bug.php?id=63666 Also note that this can probably be back-ported into other 5.x branches where this is applicable. I have only personally checked out the latest release branch at this time. Thanks! On Sat, Dec 1, 2012 at 6:06 PM, Christopher Jones christopher.jo...@oracle.com wrote: On 12/01/2012 10:21 AM, Paul Taulborg wrote: [php_date.c patch] Thanks for the patch. To ensure it isn't lost, can you open a bug at https://bugs.php.net/ and attach it? And/or submit a pull request at https://github.com/php/php-src Regards, Chris -- christopher.jo...@oracle.com http://twitter.com/ghrd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: internals Digest 2 Dec 2012 00:53:48 -0000 Issue 2845
Isn't this need basically covered by accessors? https://wiki.php.net/rfc/propertygetsetsyntax-as-implemented - Rasmus On Sat, Dec 1, 2012 at 7:53 PM, internals-digest-h...@lists.php.net wrote: From: Sebastian Krebs krebs@gmail.com To: PHP internals list internals@lists.php.net Cc: Date: Sat, 1 Dec 2012 13:34:58 +0100 Subject: Abstract properties Hi, Don't want to start a big discussion, but is there a concrete reason, why abstract properties (or a kind of abstract) are not supported? I've learned, that an interface [the concept, not the implementations within a language] is the sum of all accessible (-- public) methods and properties, what as far as I understand means, that properties could (and should) be defineable in concrete interfaces too interface Queue { public function enqueue($value); public function dequeue(); public $top; } // or abstract class Queue { abstract public function enqueue($value); abstract public function dequeue(); abstract public $top; } Of course in the second example the abstract is kind of useless, but it's for illustration. I've seen some cases (for example the example above), where it would be useful to define properties in interfaces, but instead I was forced to (in my eyes) misuse [1] methods. Right now I cannot safely write somethig like /** * Must have a $top property */ interface Queue { public function enqueue($value); public function dequeue(); } function foo(Queue $q) { doSomethingWithTop($q-top); } Because I can never ensure, that $top exists. I always have to work with isset() here (or of course I use a getter, as mentioned earlier), what takes a little bit from the usefulness of interfaces ^^ The interface feels incomplete. Would like to hear some opinions, or maybe a summary of earlier discussions about this topic :) Regards, Sebastian