[php-maint] Timezone querying
Raphael Geissert
geissert at debian.org
Wed Mar 17 23:46:29 UTC 2010
On 17 March 2010 14:17, Filipus Klutiero <chealer at gmail.com> wrote:
> Sean, let's do that. I'll recap what I wrote in my 3 last mails.
>
> Hi all,
> at the end of February, PHP 5.3 came to me, with an expected number of issues. One issue that annoyed me was that a warning is now triggered if a time-related function is used without having set the timezone in 3 approved ways: the TZ environment variable, the date.timezone PHP directive or calling date_default_timezone_set(). Thankfully, Sean Finney made Debian's PHP quiet this warning - so PHP now relies on the system timezone (PHP was already able to use that as a last recourse, but considered it unreliable, for an obscure reason).
>
That actually needs to be fixed, because the results are actually
incorrect (in spite of the tz foo patch):
$ cat /etc/timezone
America/Mexico_City
$ php -nr 'var_dump(date_default_timezone_get());'
string(15) "America/Chicago"
> But I saw something worrying related to that when attending Rasmus Lerdorf's Confoo talk on PHP Performance. The slides are available at http://talks.php.net/show/confoo10/
> Slides 16 to 20 are relevant. Slide 20 shows that with HipHop PHP, running an application relying on the system timezone causes the application to run 25% slower (before using date_default_timezone_set, 20% of the time is spent in HPHP::TimeZone::Current).
>
> I don't know for sure that baseline PHP is affected as badly, but it seems so. I seem to remember the issue is that each determination of the timezone causes a syscall - not sure again. It would be nice if somebody could check this...
It is not a syscall (well, it requires a data structure obtained from
a syscall, but...), and on its own it doesn't take that long:
0.000141 time(NULL <unfinished ...>
0.000078 SYS_time(0, 0x872a9a0, 0, 0xbfab01c0, 0x8e16b40)
= 0x4ba1652e <0.000017>
0.000118 <... time resumed> )
= 1268868398 <0.000157>
0.000041 localtime_r(0xbfab01ec, 0xbfab01c0, 0xbfab0298, 0x8e16b40,
27) = 0xbfab01c0 <0.000058>
What _is_ a problem is that before that's done, the
/usr/share/zoneinfo directory (and contents) is stat()ed followed by
lots of string comparisons which in total take some time. What does
seem pretty inefficient is this:
0.000169 strcasecmp("utc", "CST")
= 18 <0.000047>
0.000144 strcasecmp("gmt", "CST")
= 4 <0.000046>
0.000136 strcasecmp("CST", "acst")
= 2 <0.000046>
0.000137 strcasecmp("CST", "acst")
= 2 <0.000046>
0.000135 strcasecmp("CST", "acst")
= 2 <0.000045>
0.000135 strcasecmp("CST", "acst")
= 2 <0.000045>
0.000135 strcasecmp("CST", "act")
= 2 <0.000046>
0.000137 strcasecmp("CST", "act")
= 2 <0.000046>
0.000134 strcasecmp("CST", "act")
= 2 <0.000046>
0.000139 strcasecmp("CST", "act")
= 2 <0.000046>
0.000133 strcasecmp("CST", "addt")
= 2 <0.000049>
0.000159 strcasecmp("CST", "addt")
= 2 <0.000046>
0.000135 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000133 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000133 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000133 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000154 strcasecmp("CST", "adt")
= 2 <0.001151>
[no idea why it took so long that one]
0.001294 strcasecmp("CST", "adt")
= 2 <0.000048>
0.000143 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "adt")
= 2 <0.000046>
0.000134 strcasecmp("CST", "aft")
= 2 <0.000046>
<lots more skipped. Yes, comparing the same strings multiple times>
Talking about performance (and efficiency), running a one-liner
var_dump(''); with -n, shows this:
$ grep -c ^free /tmp/trace
13511
yep, 13k calls to free() in a very simple script.
Cheers,
--
Raphael Geissert - Debian Developer
www.debian.org - get.debian.net
More information about the pkg-php-maint
mailing list