[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