php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40363 Large Memory Usage and Slowness on strtotime() When Timezone is Not Set
Submitted: 2007-02-05 14:29 UTC Modified: 2010-12-20 12:23 UTC
From: r dot craig at chester dot ac dot uk Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 5.2.0 OS: Linux 2.6.5-7.282-bigsmp
Private report: No CVE-ID: None
 [2007-02-05 14:29 UTC] r dot craig at chester dot ac dot uk
Description:
------------
Performance of the attached script is 10 times slower and uses 30 times as much memory as it does on PHP 5.1.6.

I am not sure if it is strtotime(), this is where I first noticed the problem. And if i take out the strtotime(), it is fine. However strtotime() does not in itself take any longer.

Configure Command =>  './configure' '--with-freetype' '--with-apxs2=/usr/sbin/apxs2' '--with-mssql' '--with-gettext' '--with-ldap' '--with-pspell' '--enable-s
hared' '--with-jpeg-dir=/usr' '--enable-gd-native--ttf' '--with-zlib' '--enable-magic-quotes' '--with-openssl' '--with-mysqli' '--with-mysql' '--enable-memory
-limit' '--with-tidy=/usr/src/tidy' '--with-config-file-path=/usr/local/Zend/etc/' '--enable-soap'
Server API => Command Line Interface


Reproduce code:
---------------
<?php

print_mem();
$t= return_some_stuff(); /** remove the assignment this is fine performance wise, but still uses memory */

$start = microtime(true); $count =4;

print_mem();

for($i=0; $i<$count; $i++) test1();

$diff = microtime(true) - $start;
echo "Total Time: $diff ms ($count) , avergage: " .($diff/$count) .  "<br/>\n\n"; print_mem();

function test1(){
        for($i=0; $i<3000; $i++){
            strtotime ('2005-09-01');
  /** if i take out the strtotime, or change it to microtime() or some other NDF, performance is fine */
        }
}
function return_some_stuff () {
        for($i=0; $i<4000; $i++){
        $x[$i]["FOOBARFOOBAR"]="FOOBAR";
    }

        foreach ($x as $tmp) {
        $element[] = $tmp['FOOBARFOOBAR'];
        }
        return $element;
}

function print_mem(){
        $mem = memory_get_usage();
        $mem_peak = function_exists('memory_get_peak_usage')? memory_get_peak_usage():$mem;
        printf("MEM %.2fMB (%.2fMB)\n\n", $mem/1024/1024, $mem_peak/1024/1024 ); }
?>


Expected result:
----------------
(As on PHP 5.1.6)

MEM 0.06MB (0.06MB)

MEM 0.31MB (0.31MB)

Total Time: 0.24065089225769 ms (4) , average: 0.060162723064423

MEM 0.31MB (0.31MB)


Actual result:
--------------
On php 5.2.0 

MEM 0.06MB (0.06MB)

MEM 0.39MB (1.19MB)

Total Time: 2.4987750053406 ms (4) , average: 0.62469375133514<br/>

MEM 9.23MB (9.23MB)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-02-05 14:36 UTC] derick@php.net
Works fine for me, do you have error_Reporting set to E_ALL | E_STRICT ?

MEM 0.07MB (0.09MB)

MEM 0.85MB (2.35MB)

Total Time: 1.058070898056 ms (4) , avergage: 0.26451772451401<br/>

MEM 0.85MB (2.35MB)



 [2007-02-05 15:35 UTC] r dot craig at chester dot ac dot uk
derick, but how does that compare to 5.1.6?

The memory increase during the strtotime() loop, I see is with no php.ini (php -c /dev/null). 

E_STRICT gives me warnings on both 5.2 and 5.1.6, "strtotime(): It is not safe to rely on the system's timezone settings... " etc.

Is it perhaps something to do with logging this warning? I thought if strict was turned off it didn't log the error at all.
 [2007-02-05 16:05 UTC] tony2001@php.net
If you remove the 4000-elements array, 5.2.0 works 3x-4x times faster than 5.1.6.
 [2007-02-05 17:37 UTC] r dot craig at chester dot ac dot uk
If I remove the strtotime() and just have the 4000 element array, it also works faster. 

If I just remove the _assignment_ from the return_some_stuff() if also works much faster.

But this is a sumation of a live peice of code. I want to make a 4000 array and then call strtotime 3000 times times (Is this so Odd?). This is 10 times slower in 5.2.0 and uses 30 times as much memory.

If I take out all the code and just have "echo 'Hello World'", It's also much faster, but that's not quite what I want to do!
 [2007-02-05 17:48 UTC] tony2001@php.net
I don't understand what you're talking about.
Your code works 3x faster with 5.2.0 even WITH the array stuff.
0.37447214126587 (5.2.0) vs 0.96990513801575 (5.1.6)

Try to set the timezone correctly?
 [2007-02-06 08:57 UTC] r dot craig at chester dot ac dot uk
If I put date_default_timezone_set("Europe/London") at the top, performance is fine. 

But what was causing the slow-down and memory-usage? Any why only with the with the array assignment (Which was not timed)?

Is it something to do with the E_NOTICEs? A notice was generated in E_STRICT on 5.1.6 but it didn't affect performance.
 [2007-02-06 09:44 UTC] tony2001@php.net
Set the timezone correctly, otherwise it's expected to spend time trying to "autodetect" your timezone based on your system settings and looking in the timezone db.
 [2007-02-06 13:11 UTC] r dot craig at chester dot ac dot uk
I shall modify the bug to reflect that this happens only when invalid timezone is set. 

Is it also expected to spend MEM 8MB auto detecting the timezone? It doesn't do this on 5.1.6.

It also doesn't actually spend the time detecting the timezone, as you have said, removing the loop that creates the array it is perfectly fine. The array loop itself is not inside the timing loop.

Is this reproducible on 5.2.0 then with an invalid timezone?

Is this behaviour expected?
 [2010-12-20 12:23 UTC] jani@php.net
-Package: Tidy +Package: Date/time related
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 05 13:01:30 2024 UTC