php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49996 DateTimeZone::getTransitions performance drop
Submitted: 2009-10-26 13:16 UTC Modified: 2010-02-18 01:00 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (50.0%)
From: dor at videocells dot com Assigned: derick (profile)
Status: No Feedback Package: Performance problem
PHP Version: 5.3.0 OS: Centos 5.2 64 bit
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2009-10-26 13:16 UTC] dor at videocells dot com
Description:
------------
Hi, it seems to me that the DateTimeZone::getTransitions() function suffered a performance loss of some degree between php 5.2.9 and 5.3

each call to it takes about one tenth of a second.

I noticed this because I happen to have a function that recieves many timezones and checks the transistions of each of them.
Recently I discovered a performance loss on my web gui, and after some research i found out that for some reason the getTransitions() function takes a noticable amount of time to run. much
more than with php 5.2.9 for the same request to complete.

note that since we worked with previous versions of php, it is called without the new parameters added in php 5.3

Reproduce code:
---------------
$TimezonesToAdd = array (
	"(GMT -12:00) International Date Line West" => "Etc/GMT+12", 	"(GMT -11:00) Midway Island, Samoa" => "Pacific/Midway",
	"(GMT -10:00) Hawaii" => "US/Hawaii",
        // many many more time zones...
	"(GMT +12:00) Auckland, Wellington" => "Pacific/Auckland",
"(GMT +12:00) Fiji, Kamchatka, Marshall Is." => "Asia/Kamchatka",
	"(GMT +13:00) Nuku'alofa" => "Pacific/Tongatapu");
foreach ($TimezonesToAdd as $TimezoneDescription => $TimezoneID)
{
    EnsureTimezoneExists ($TimezoneID);
    self::$_AvailableTimezones [$TimezoneID] = $TimezoneDescription;
}
function EnsureTimezoneExists($TimezoneID)
{
    $res = timezone_open($TimezoneID)
    if($res)
    {
        $TimeInTimezone = new DateTime ("now",$res)
        //the following line takes alot of time :
        $trans = $res->getTransitions();
    }
}

Expected result:
----------------
The $res->getTransitions() call should cost in the magnitude of 0.001 seconds, but instead it takes about 0.1 seconds, which is noticable.

Actual result:
--------------
microtime() calls before and after the function call, show that the function takes about 0.1 seconds to run

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-26 22:49 UTC] jani@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

And preferrably such which does not have several syntax errors and missing parts.. 
 [2009-10-27 06:55 UTC] dor at videocells dot com
<?php
$timezoneArray = array (
"(GMT -12:00) International Date Line West" => "Etc/GMT+12",
"(GMT -11:00) Midway Island, Samoa" => "Pacific/Midway",
"(GMT -10:00) Hawaii" => "US/Hawaii",
// many many more time zones...
"(GMT +12:00) Auckland, Wellington" => "Pacific/Auckland",
"(GMT +12:00) Fiji, Kamchatka, Marshall Is." => "Asia/Kamchatka",
"(GMT +13:00) Nuku'alofa" => "Pacific/Tongatapu");

foreach ($timezoneArray as $TimezoneDescription => $TimezoneID)
{
    $res = timezone_open($TimezoneID)
    if($res)
    {
        $TimeInTimezone = new DateTime ("now",$res)
        $microParts = explode(" ",microtime());
        list($a,$b) = explode(".",$microParts[0]);
        echo "before : ".strftime('%Y%m%d-%H%M%S',time()).".".$b;        
        //the following line takes alot of time :        
        $trans = $res->getTransitions();
        $microParts_2 = explode(" ",microtime());
        list($c,$d) = explode(".",$microParts_2[0]);
        echo "before : ".strftime('%Y%m%d-%H%M%S',time()).".".$d;    }
   
}
 [2009-10-27 22:27 UTC] jani@php.net
With this simplified and working (!) script I get exactly same results 
with PHP_5_2, PHP_5_3 and HEAD of today:

<?php
$timezoneArray = array (
"(GMT -12:00) International Date Line West" => "Etc/GMT+12",
"(GMT -11:00) Midway Island, Samoa" => "Pacific/Midway",
"(GMT -10:00) Hawaii" => "US/Hawaii",
// many many more time zones...
"(GMT +12:00) Auckland, Wellington" => "Pacific/Auckland",
"(GMT +12:00) Fiji, Kamchatka, Marshall Is." => "Asia/Kamchatka",
"(GMT +13:00) Nuku'alofa" => "Pacific/Tongatapu");

foreach ($timezoneArray as $TimezoneDescription => $TimezoneID)
{
  $res = timezone_open($TimezoneID);
  if($res)
  {
    $start = microtime(true);
    $trans = $res->getTransitions();
    $end = microtime(true);
    var_dump(1000 * ($end - $start));
  }
}
?>

Now, where is the performance issue here?
 [2009-10-28 06:56 UTC] dor at videocells dot com
I have two exact computers in terms of OS installation and apache/php configuration (except the php 5.3 against php 5.2.9)

the average speed this function takes to run in php 5.2.9 is :
float(0.015974044799805) float(0.0457763671875) float(0.045061111450195) float(0.65398216247559) float(0.92506408691406) float(0.70810317993164) float(0.19216537475586) float(0.32210350036621) float(0.73885917663574) float(0.16283988952637) float(0.94914436340332) float(0.62394142150879) float(0.25200843811035)....
while on php 5.3 its :
float(63.025951385498) float(62.762022018433) float(62.709093093872) float(63.004970550537) float(63.482046127319) float(63.012838363647) float(62.775135040283) float(62.896966934204) float(63.131093978882) float(63.91716003418) float(63.18211555481) ....

its 60 times slower.

can i somehow send a print screen, or attach the printouts of both computer's phpinfo() ?
 [2009-10-28 07:52 UTC] derick@php.net
It's indeed quite a bit slower... not sure if this is a *bug* though, but will check it out.
 [2010-02-10 16:57 UTC] derick@php.net
Are you using Centos' packages?
 [2010-02-18 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-10-20 04:01 UTC] rstein2000 at gmail dot com
I am experiencing the same issue.

The PHP is built through cPanel's easyapache script from your sources and is 
currently affecting PHP 5.3.3.  Platform is CentOS.

Test code to replicate the issue:

<?php
$timezone = "UTC";
$tz = new DateTimeZone($timezone);
$tzarray = $tz->getTransitions();
?>

Just calling getTransitions(); is enough to trigger the regression.  Time tests 
with and without that call:

With:
time php -q tztest.php
real 0m0.459s
user 0m0.404s
sys 0m0.054s

Without:
time php -q tztest.php
real 0m0.092s
user 0m0.023s
sys 0m0.068s
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Fri Dec 09 02:05:54 2022 UTC