[Bench] Problème avec memory_get_usage()
Posté : 21 févr. 2008, 18:04
Bonjour,
Ce n'est pas souvent que je demande de l'aide, mais là, je suis tombé sur un problème de bench. Ma question va peut être vous paraître un peu conne, mais c'est la première de toute une série, parce que le comportement de php me trouble un peu, et ca me gène dans mes benchs de mémoire.
Donc, après pas mal de problèmes, je suis revenu à un script très simple, qui compare la consommation mémoire du stockage du même volume de données (à peu de choses près) dans respectivement un tableau dans un objet (objetif de mes benchs), un tableau, et des variables. Les données sont une liste de 1000 variables de 5 à 10 caractères générées aléatoirement.
On a ce résultat :
(Au passage ce n'est pas une confusion entre octets et bits puisque mon système me donnait grosso modo la même consommation de mémoire pour php).
Ensuite, concernant l'objet, sachant que les données sont stockées sous forme de tableau, est ce normal que la consommation de mémoire soit presque deux fois plus importante ?
Si quelqu'un avait sa petite idée, ce serait pas mal
Merci par avance de vos réponses.
Annexes :
Script de test :
Classe testée :
Ce n'est pas souvent que je demande de l'aide, mais là, je suis tombé sur un problème de bench. Ma question va peut être vous paraître un peu conne, mais c'est la première de toute une série, parce que le comportement de php me trouble un peu, et ca me gène dans mes benchs de mémoire.
Donc, après pas mal de problèmes, je suis revenu à un script très simple, qui compare la consommation mémoire du stockage du même volume de données (à peu de choses près) dans respectivement un tableau dans un objet (objetif de mes benchs), un tableau, et des variables. Les données sont une liste de 1000 variables de 5 à 10 caractères générées aléatoirement.
On a ce résultat :
Or, d'après la doc php, memory_get_usage() retourne un résultat en octets, et j'ai du mal à croire que php ait besoin de 176ko soit 176 octets par variable pour stocker ces données, qui font au maximum 6 octets pour le nom de la variable, et 10 octets pour la valeur. Donc les 160 octets restants pour la structure, j'y crois pas trop… Est ce que quelqu'un sait d'où cela pourraît venir et si c'est un comportement normal ?reel obj : 524288 - 262144 = 262k
emalloc obj : 477216 - 161200 = 316k
reel tab : 786432 - 524288 = 262k
emalloc tab : 653744 - 477216 = 176k
reel var : 1048576 - 786432 = 262k
emalloc var : 830112 - 653744 = 176k
(Au passage ce n'est pas une confusion entre octets et bits puisque mon système me donnait grosso modo la même consommation de mémoire pour php).
Ensuite, concernant l'objet, sachant que les données sont stockées sous forme de tableau, est ce normal que la consommation de mémoire soit presque deux fois plus importante ?
Si quelqu'un avait sa petite idée, ce serait pas mal
Merci par avance de vos réponses.
Annexes :
Script de test :
<?php
ini_set('memory_limit', '256M');
require('../includes/template.class.php.new');
template::defroot('../templates/');
template::$extract = FALSE;
$tpl = new template('test');
$body = new template('testbody');
//$tpl->body = $body;
$mr = memory_get_usage(TRUE);
$me = memory_get_usage();
for($i=0; $i<1000; $i++)
{
$tmp = '';
$length = mt_rand(5, 10);
for($n=0;$n<$length;$n++)
{
$tmp .= chr(mt_rand(48, 122));
}
$body->{'var' . $i} = $tmp;
}
$mr2 = memory_get_usage(TRUE);
$me2 = memory_get_usage();
echo '<br />reel 1 : ' . "\t" . $mr2 . ' - ' . $mr . ' = ' . intval(($mr2 - $mr)/1000) . 'k';
echo '<br />emalloc 1 : ' . "\t" . $me2 . ' - ' . $me . ' = ' . intval(($me2 - $me)/1000) . 'k';
$arr = array();
for($i=0; $i<1000; $i++)
{
$tmp = '';
$length = mt_rand(5, 10);
for($n=0;$n<$length;$n++)
{
$tmp .= chr(mt_rand(48, 122));
}
$arr['var' . $i] = $tmp;
}
$mr = memory_get_usage(TRUE);
$me = memory_get_usage();
echo '<br />reel 2 : ' . "\t" . $mr . ' - ' . $mr2 . ' = ' . intval(($mr - $mr2)/1000) . 'k';
echo '<br />emalloc 2 : ' . "\t" . $me . ' - ' . $me2 . ' = ' . intval(($me - $me2)/1000) . 'k';
for($i=0; $i<1000; $i++)
{
$tmp = '';
$length = mt_rand(5, 10);
for($n=0;$n<$length;$n++)
{
$tmp .= chr(mt_rand(48, 122));
}
${'var' . $i} = $tmp;
}
$mr2 = memory_get_usage(TRUE);
$me2 = memory_get_usage();
echo '<br />reel 3 : ' . "\t" . $mr2 . ' - ' . $mr . ' = ' . intval(($mr2 - $mr)/1000) . 'k';
echo '<br />emalloc 3 : ' . "\t" . $me2 . ' - ' . $me . ' = ' . intval(($me2 - $me)/1000) . 'k';
/*
$mc = microtime(TRUE);
$gm = memory_get_usage();
echo '<br />m3 : ' . memory_get_usage();
$tpl->__parse(array(),FALSE);
echo '<br />m4 : ' . memory_get_usage();
echo '<br />b2 : ' . (memory_get_peak_usage() - $gm)/1000 . 'k';
echo '<br />b2 : ' . (microtime(TRUE) - $mc);*/
?>
Classe testée :
<?php
class template
{
(...)
private $vars = array();
(...)
public function __set($var, $val)
{
$this->vars[$var] = $val;
}
public function __get($var)
{
return isset($this->vars[$var]) ? $this->vars[$var] : NULL;
}
public function __isset($var)
{
return array_key_exists($var, $this->vars);
}
public function __unset($var)
{
if( isset($this->vars[$var]) )
{
unset($this->vars[$var]);
}
}
(...)
}
?>