Re: Pointers For Newbies, Reminders For Oldies

From: Date: Thu, 28 Jan 2010 15:02:56 +0000
Subject: Re: Pointers For Newbies, Reminders For Oldies
References: 1 2 3 4  Groups: php.general 
Request: Send a blank email to php-general+get-301611@lists.php.net to get a copy of this message
Nathan Rixham wrote:
Ford, Mike wrote:
-----Original Message----- From: Rene Veerman [mailto:rene7705@gmail.com] 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

« previous php.general (#301611) next »