Je me rends compte que le second évite la surcharge d'un appel de fonction ( update , est en fait une construction de langage), mais il serait intéressant de savoir si l'une est meilleure que l'autre. J'utilise unset()
pour la plupart de mes opérations de codage, mais j'ai récemment examiné quelques classes respectables trouvées hors réseau qui utilisent plutôt $var = null
.
Y at-il un préféré, et quel est le raisonnement?
Il a été mentionné dans la page du manuel unset en 2009 :
unset()
fait exactement ce que son nom l'indique - désactive une variable. Cela ne force pas la libération immédiate de la mémoire. Le ramasse-miettes de PHP le fera à sa guise - par intention dès que possible, car ces cycles de processeur ne sont de toute façon pas nécessaires, ou jusqu'à ce que le script manque de mémoire, peu importe ce qui se passe en premier.Si vous faites
$whatever = null;
, vous réécrivez les données de la variable. La mémoire peut être libérée/réduite plus rapidement, mais le programme qui en a vraiment besoin plus rapidement peut être volé plus rapidement, ce qui allonge le temps d’exécution.
(Depuis 2013, cette unset
page de manuel n'inclut plus cette section)
Notez que jusqu'à php5.3, si vous avez deux objets dans une référence circulaire , comme dans une relation parent-enfant, appeler unset () sur l'objet parent ne libérera pas la mémoire utilisée pour la référence parente dans l'enfant objet. (La mémoire ne sera pas libérée non plus lorsque l'objet parent sera ramassé.) ( bug 33595 )
La question " différence entre unset et = null " détaille quelques différences:
unset($a)
supprime également $a
de la table des symboles; par exemple:
$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);
Les sorties:
Notice: Undefined variable: a in xxx
NULL
Mais quand
$a = null
est utilisé:
$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Outputs:
NULL
Il semble que
$a = null
soit un peu plus rapide que son équivalentunset()
: mettre à jour une entrée de la table des symboles semble être plus rapide que de la supprimer.
unset
), une erreur est déclenchée et la valeur de l'expression de la variable est null. (Parce que, quoi d'autre devrait PHP faire? Chaque expression doit donner une valeur.) unset
n'est pas réellement une fonction, mais un construction du langage. Ce n'est pas plus un appel de fonction qu'un return
ou un include
.
Outre les problèmes de performances, l'utilisation de unset
rend le code intention de votre code beaucoup plus clair.
En faisant un unset (()) sur une variable, vous avez essentiellement marqué la variable pour «garbage collection» (PHP n'en a pas vraiment, mais par exemple) afin que la mémoire ne soit pas immédiatement disponible. La variable n'héberge plus les données, mais la pile reste à la taille la plus grande. Faire la méthode null supprime les données et réduit la mémoire de pile presque immédiatement.
Cela vient d’expériences personnelles et d’autres aussi. Voir les commentaires de la fonction unset () ici .
Personnellement, j'utilise unset () entre les itérations d'une boucle pour ne pas avoir à attendre que la pile ait une taille yo-yo'd. Les données ont disparu, mais l'empreinte reste. À la prochaine itération, php utilise déjà la mémoire et initialise plus rapidement la variable suivante.
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
Il semble que "= null" soit plus rapide.
Résultats de PHP 5.4:
Résultats PHP 5.3:
Résultats de PHP 5.2:
Résultats PHP 5.1:
Les choses commencent à être différentes avec PHP 5.0 et 4.4.
5.0:
4.4:
Gardez à l'esprit que microtime (true) ne fonctionne pas dans PHP 4.4, j'ai donc dû utiliser l'exemple microtime_float donné dans php.net/microtime/Example # 1.
Cela fait une différence avec les éléments de tableau.
Considérez cet exemple
$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
Ici, la clé 'test' existe toujours. Cependant, dans cet exemple
$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
la clé n'existe plus.
Cela fonctionne différemment pour les variables copiées par référence:
$a = 5;
$b = &$a;
unset($b); // just say $b should not point to any variable
print $a; // 5
$a = 5;
$b = &$a;
$b = null; // rewrites value of $b (and $a)
print $a; // nothing, because $a = null
En ce qui concerne les objets, en particulier dans le scénario de chargement différé, il convient de considérer que le récupérateur de mémoire fonctionne dans des cycles de processeur inactifs. Par conséquent, le fait de supposer que vous rencontrez des problèmes lorsque de nombreux objets chargent une petite pénalité de temps résoudra la libération de mémoire.
Utilisez time_nanosleep pour permettre au CPG de collecter de la mémoire . Il est souhaitable de définir la variable sur null.
Testé sur le serveur de production, à l'origine, le travail consommait 50 Mo puis était arrêté . Après l'utilisation de nanosleep, 14 Mo correspondaient à une consommation de mémoire constante.
Il faut dire que cela dépend du comportement du CPG, qui peut changer de version PHP à version . Mais cela fonctionne sous PHP 5.3.
par exemple. cet exemple (code pris sous forme de flux Google VirtueMart2)
for($n=0; $n<count($ids); $n++)
{
//unset($product); //usefull for arrays
$product = null
if( $n % 50 == 0 )
{
// let GC do the memory job
//echo "<mem>" . memory_get_usage() . "</mem>";//$ids[$n];
time_nanosleep(0, 10000000);
}
$product = $productModel->getProductSingle((int)$ids[$n],true, true, true);
...
J'en doute toujours, mais je l'ai essayé avec mon script et j'utilise xdebug pour savoir en quoi cela affectera l'utilisation de la mémoire de mon application . Le script est défini sur ma fonction comme suit:
function gen_table_data($serv, $coorp, $type, $showSql = FALSE, $table = 'ireg_idnts') {
$sql = "SELECT COUNT(`operator`) `operator` FROM $table WHERE $serv = '$coorp'";
if($showSql === FALSE) {
$sql = mysql_query($sql) or die(mysql_error());
$data = mysql_fetch_array($sql);
return $data[0];
} else echo $sql;
}
Et j'ajoute unset juste avant le code return
et il me donne: 160200 Puis j'essaie de le changer avec $sql = NULL
et cela me donne: 160224 :)
Mais il y a quelque chose d'unique sur ce comparatif quand je n'utilise pas unset () ou NULL, xdebug me donne 160144 comme utilisation de la mémoire
Donc, je pense que donner une ligne à utiliser unset () ou NULL ajoutera un processus à votre application et il sera préférable de rester Origin avec votre code et de réduire la variable que vous utilisez aussi efficacement que possible.
Corrigez-moi si je me trompe, merci
J'ai créé un nouveau test de performance pour unset
et =null
, car, comme indiqué dans les commentaires, l'erreur écrite ici est une erreur (la recréation des éléments). J'ai utilisé des tableaux, comme vous voyez, cela importait moins maintenant.
<?php
$arr1 = array();
$arr2 = array();
for ($i = 0; $i < 10000000; $i++) {
$arr1[$i] = 'a';
$arr2[$i] = 'a';
}
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$arr1[$i] = null;
}
$elapsed = microtime(true) - $start;
echo 'took '. $elapsed .'seconds<br>';
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
unset($arr2[$i]);
}
$elapsed = microtime(true) - $start;
echo 'took '. $elapsed .'seconds<br>';
Mais je ne peux le tester que sur un serveur PHP 5.5.9, voici les résultats: - a pris 4.4571571350098 secondes - a pris 4.4425978660583 secondes
Je préfère unset
pour des raisons de lisibilité.
unset
code sinon libérer la mémoire immédiate est toujours très utile et serait une bonne pratique de le faire chaque fois que nous passons des étapes de code avant de quitter une méthode. notez qu'il ne s'agit pas de libérer de la mémoire immédiate. La mémoire immédiate est destinée au processeur, qu’en est-il de la mémoire secondaire qui est de la RAM.
et cela concerne également la prévention des fuites de mémoire.
veuillez consulter ce lien http://www.hackingwithphp.com/18/1/11/be-wary-of-garbage-collection-part-2
j'utilise unset depuis longtemps maintenant.
une meilleure pratique comme celle-ci dans le code consiste à désinstaller instantanément toutes les variables déjà utilisées en tant que tableau.
$data['tesst']='';
$data['test2']='asdadsa';
....
nth.
et just unset($data);
pour libérer toutes les utilisations de variables.
s'il vous plaît voir le sujet connexe pour désactiver
Quelle est l'importance de supprimer des variables en PHP?
[punaise]
PHP 7 a déjà travaillé sur de tels problèmes de gestion de la mémoire et son utilisation réduite à minimale.
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
PHP 7.1 Outpu:
a pris 0.16778993606567 secondes .__ a pris 0,16630101203918 secondes
Pour mémoire, en excluant le temps qu'il faut:
<?php
echo "<hr>First:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Unset:<br>";
unset($x);
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Null:<br>";
$x=null;
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>function:<br>";
function test() {
$x = str_repeat('x', 80000);
}
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Reasign:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
Il retourne
First:
438296
438352
Unset:
438296
438352
Null:
438296
438352
function:
438296
438352
Reasign:
438296
520216 <-- double usage.
Conclusion: mémoire libre nulle et non définie comme prévu (pas seulement à la fin de l'exécution). De plus, la réaffectation d'une variable conserve la valeur deux fois à un moment donné (520216 contre 438352)