Re: Pointers For Newbies, Reminders For Oldies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Nathan Rixham wrote:
Ford, Mike wrote:
-----Original Message-----
From: Rene Veerman [mailto:rene7705@xxxxxxxxx]
Sent: 27 January 2010 22:46

And if your script needs to pass large (> 5Mb) arrays around to
functions, be sure to use passing-by-reference; failing to do so can
double your memory requirements,
possibly hitting the ini_set('memory_lmit', ??)
Have you benchmarked this? PHP's copy-on-change philosophy means there shouldn't be much difference in memory terms -- so unless you actually expect to change the array's contents, you should pass by value.

As proof, I constructed this little test:

	function test($arg, $base_mem)
	{
		echo "Additional inside func = ", memory_get_usage()-$base_mem, "<br />\n";
	}


try changing this to access the array in some way such as:

function test($arg, $base_mem)
{
 foreach( $arg as $index => $value ) {

 }
 echo "Additional= ", memory_get_usage()-$base_mem, "\n";
}

After array creation = 52696
Additional = 101152
Final = 117200

vs: function test(&$arg, $base_mem)

After array creation = 52696
Additional = 53104
Final = 101696

there's the double memory usage

I don't know what you guys are doing wrong but the following should be the correct behaviour:

<?php

function get_memory( $init=false )
{
    static $base = null;
    if( $base === null || $init )
    {
        $base = memory_get_usage();
    }

    return memory_get_usage() - $base;
}

function simple_access( $data )
{
    $foo = $data[100];
    echo 'Memory: '.get_memory().' (simple access)'."\n";
}

function foreach_value_access( $data )
{
    foreach( $data as $value )
    {
        $foo = $value;
        break;
    }
    echo 'Memory: '.get_memory().' (foreach value access)'."\n";
}

function foreach_key_access( $data )
{
    foreach( $data as $key => $value )
    {
        $foo = $key;
        $foo = $value;
        break;
    }
    echo 'Memory: '.get_memory().' (foreach key/value access)'."\n";
}

function modify_single_access( $data )
{
    $data[100] = str_repeat( '@', 10000 );
    echo 'Memory: '.get_memory().' (modify single access)'."\n";
}

function modify_all_access( $data )
{
    for( $i = 0; $i < 1000; $i++ )
    {
        $data[$i] = str_repeat( '@', 10000 );
    }

    echo 'Memory: '.get_memory().' (modify all access)'."\n";
}


get_memory( true );

$data = array();
for( $i = 0; $i < 1000; $i++ )
{
    $data[$i] = str_repeat( '#', 10000 );
}

echo 'Memory: '.get_memory().' (data initialized)'."\n";

simple_access( $data );
foreach_value_access( $data );
foreach_key_access( $data );
modify_single_access( $data );
modify_all_access( $data );

?>

I get the following output (PHP 5.2.11 from command-line):

    Memory: 10160768 (data initialized)
    Memory: 10161008 (simple access)
    Memory: 10161104 (foreach value access)
    Memory: 10161240 (foreach key/value access)
    Memory: 10267312 (modify single access)
    Memory: 20321576 (modify all access)

I don't double up on memory consumption until I force the write onto every element... this is expected because internally every array element is individually subject to the Copy-On-Write (COW) principle since each element is internally stored as a zval just like the array itself.

Cheers,
Rob.
--
http://www.interjinn.com
Application and Templating Framework for PHP

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux