对于PHP,如果创建新数组或向现有数组添加相同的索引,内存使用会有很大差异吗?

If I am creating an array with several hundred indexes, how much overhead is required for the additional array versus adding a second dimension to an existing array?

I.E. $pages['page']['url'] and $titles['page']['title'] versus $pages['page']['url']['title'] versus $pages['page']['title'], where the last example assumes each index of $pages contains an associative array.

The goal is to be able to be to lookup two attributes of each 'page'. Each 'page' has a 'url' and a 'title', which would be more efficient for memory usage on the arrays? Which for access/storing the data?

Two associative arrays:

// Store the information in arrays
$titles['page1'] = 'Page 1 Title';
$titles['page2'] = 'Page 2 Title';

$urls['page1'] = 'http://www.page1.com';
$urls['page2'] = 'http://www.page2.com';

// Display an example
echo $titles['page1'] . ' is at ' . $urls['page1']; 

or one array of arrays:

$pages['page1'] = array( 'title' => 'Page 1 Title', 'url' => 'http://www.page1.com' );
$pages['page2'] = array( 'title' => 'Page 2 Title', 'url' => 'http://www.page2.com' );

// Display an example
echo $pages['page1']['title'] . ' is at ' . $pages['page1']['url'];

The memory usage of a two dimensional array is slightly bigger, but this may result from bad code (?).

<!--
    http://php.net/manual/en/function.memory-get-usage.php

    array1: 116408 (1D 1001 keys)     (1x 100.000 keys:  11.724.512)
    array2: 116552 (2D, 1002 keys)    (2x  50.000 keys:  11.724.768)

    total:    +144                                             +256
-->

<?php

function genRandomString() {
    $length = 10;
    $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
    $string = '';    

    for ($p = 0; $p < $length; $p++) {
        $string .= $characters[mt_rand(0, strlen($characters))];
    }

    return $string;
}

$i = 0;

// ----- Larger 1D array -----
$mem_start = memory_get_usage();
echo "initial1: " . $mem_start . "<br />";
$arr = array();

for ($i = 1; $i <= 1000; $i++) {
    $arr[ genRandomString() ] = "Hello world!";
}

echo "array1: " . (memory_get_usage() - $mem_start) . "<br />";
unset($arr);

// ----- 2D array -----
$mem_start = memory_get_usage();
$arr2 = array();

echo "initial2: " . $mem_start . "<br />"; 


for ($i = 1; $i <= 500; $i++) {
    $arr2["key______1"][ genRandomString() ] = "Hello world!";
    $arr2["key______2"][ genRandomString() ] = "Hello world!";
}

echo "array2: " . (memory_get_usage() - $mem_start) . "<br />";

unset($arr2);

unset($i);
unset($mem_start)    
echo "final: " . memory_get_usage() . "<br />"; 

?>

One array consume less memory than two:

 total mem two arrays: 2496
 total mem one array: 1848

I do calculations assign 'aaaa' to each element in one and two arrays, capturing memory_get_usage().

EDIT: CORRECTION: If one of these is one level array, is better two arrays than one.

Added the code. I moddifie it to put more elements to the array and do one array with only one level:


total mem two arrays: 1,009,720

total mem one array: 1,011,112

$memI = memory_get_usage();

for ($i = 0; $i < 1000; $i++)
{
     $pages[uniqid()][uniqid()] = 'aaaa';
     $titles[uniqid()] = 'aaaa';
}

$memF = memory_get_usage();

$memCalc = $memF - $memI;

echo "<pre>total mem two arrays: " . number_format($memCalc);


unset($pages);
unset($titles);

$memI = memory_get_usage();

for ($i = 0; $i < 1000; $i++)
{
    $pages['page'][uniqid()][uniqid()]  = 'aaaa';
    $pages['title'][uniqid()] = 'aaaa';
}

$memF = memory_get_usage();

$memCalc = $memF - $memI;

echo "<pre>total mem one array: " . number_format($memCalc);

PHP don't has really array. PHP technically has a map, or sometimes called associatyve array. Map speed depends on number of elements, and memory usage doesn't matter on time when you add elements.

I don't think that the difference in multi-dimensional array's vs several arrays would be large enough to focus on it for memory usage, strings and int's however are quite different in memory.

Applying conventions to coding would use less ram.

Using this example:

$pages['page1'] = array( 'title' => 'Page 1 Title', 'url' => 'http://www.page1.com' );
$pages['page2'] = array( 'title' => 'Page 2 Title', 'url' => 'http://www.page2.com' );

// Display an example
echo $pages['page1']['title'] . ' is at ' . $pages['page1']['url'];

You could re-write it:

$pages[] = array('Page 1 Title','www.page1.com' );
$pages[] = array('Page 2 Title','www.page2.com' );

// Display an example
foreach ($pages as $page){
   echo $page[0] . ' is at http://' . $page[1];
}

You could also use Definitions for keys for the self-documenting code idea:

define("TITLE_KEY", 0);
define("URL_KEY", 1);
$pages[] = array(TITLE_KEY=>'Page 1 Title',URL_KEY=>'www.page1.com' );
$pages[] = array(TITLE_KEY=>'Page 2 Title',URL_KEY=>'www.page2.com' );

// Display an example
foreach ($pages as $page){
   echo $page[TITLE_KEY] . ' is at http://' . $page[URL_KEY];
}