Basé sur le code de Quazzle, j'ai exécuté le code suivant (5.4.16 windows 64bits):
<?php
class SomeClass {
public $aaa;
public $bbb;
public $ccc;
}
function p($i) {
echo '<pre>';
print_r($i);
echo '</pre>';
}
$t0 = microtime(true);
$arraysOf=array();
$inicio=memory_get_usage();
for ($i=0; $i<1000; $i++) {
$z = array();
for ($j=0; $j<1000; $j++) {
$z['aaa'] = 'aaa';
$z['bbb'] = 'bbb';
$z['ccc'] = $z['aaa'].$z['bbb'];
}
$arraysOf[]=$z;
}
$fin=memory_get_usage();
echo '<p>arrays: '.(microtime(true) - $t0)."</p>";
echo '<p>memory: '.($fin-$inicio)."</p>";
p($z);
$t0 = microtime(true);
$arraysOf=array();
$inicio=memory_get_usage();
for ($i=0; $i<1000; $i++) {
$z = new SomeClass();
for ($j=0; $j<1000; $j++) {
$z->aaa = 'aaa';
$z->bbb = 'bbb';
$z->ccc = $z->aaa.$z->bbb;
}
$arraysOf[]=$z;
}
$fin=memory_get_usage();
echo '<p>arrays: '.(microtime(true) - $t0)."</p>";
echo '<p>memory: '.($fin-$inicio)."</p>";
p($z);
$t0 = microtime(true);
$arraysOf=array();
$inicio=memory_get_usage();
for ($i=0; $i<1000; $i++) {
$z = new stdClass();
for ($j=0; $j<1000; $j++) {
$z->aaa = 'aaa';
$z->bbb = 'bbb';
$z->ccc = $z->aaa.$z->bbb;
}
$arraysOf[]=$z;
}
$fin=memory_get_usage();
echo '<p>arrays: '.(microtime(true) - $t0)."</p>";
echo '<p>memory: '.($fin-$inicio)."</p>";
p($z);
?>
Et j'ai obtenu le résultat suivant:
arrays: 1.8451430797577
memory: 460416
Array
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 1.8294548988342
memory: 275696
SomeClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 2.2577090263367
memory: 483648
stdClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
Conclusion pour php 5.4
- La classe est plus rapide que les tableaux (mais marginalement).
- stdClass est le mal.
- La classe utilise moins de mémoire que les tableaux. (environ 30 à 40% de moins !!)
ps: pour mémoire, si la classe est définie mais les membres alors, l'utilisation de cette classe est plus lente. Il utilise également plus de mémoire. Apparemment, le secret est de définir les membres
Mise à jour
J'ai mis à jour de php 5.4 à php 5.5 (5.5.12 x86 windows).
arrays: 1.6465699672699
memory: 460400
Array
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 1.8687851428986
memory: 363704
SplFixedArray Object
(
[0] => aaa
[1] => bbb
[2] => aaabbb
)
arrays: 1.8554251194
memory: 275568
SomeClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
arrays: 2.0101680755615
memory: 483656
stdClass Object
(
[aaa] => aaa
[bbb] => bbb
[ccc] => aaabbb
)
Conclusion pour php 5.5
- Pour les tableaux, PHP 5.5 est plus rapide que PHP 5.4, pour l'objet c'est à peu près la même chose
- La classe est plus lente que les tableaux grâce à l'optimisation de PHP 5.5 et des tableaux.
- stdClass est le mal.
- La classe utilise toujours moins de mémoire que les tableaux. (environ 30 à 40% de moins !!).
- SplFixedArray est similaire à l'utilisation d'une classe mais il utilise plus de mémoire.
J'ai utilisé ce code pour le "profilage" (1000 instances, 1000.000 lectures / écritures):
function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; } $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = array(); for ($j=0; $j<1000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } } echo '<p>arrays: '.(microtime(true) - $t0); p($z); $t0 = microtime(true); for ($i=0; $i<1000; $i++) { $z = (object) null; for ($j=0; $j<1000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } } echo '<p>obj: '.(microtime(true) - $t0); p($z); echo '<p> phpversion '.phpversion();
Il sort dans mon LINUX hébergeant ce truc:
arrays: 1.1085488796234 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) obj: 1.2824709415436 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) phpversion 5.2.17
donc en conclusion: les objets sont plus lents même sur PHP 5.2. N'utilisez pas d'objets à moins que vous n'ayez vraiment besoin de leurs fonctionnalités oop.
la source
J'utilise le code de magallanes sous php 7.0.9:
arrays: 0.19802498817444 memory: 324672 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.18602299690247 memory: 132376 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.1950249671936 memory: 348296 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
Et l'utilisateur php 7.1.3:
arrays: 0.59932994842529 memory: 444920 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.72895789146423 memory: 164512 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.61777496337891 memory: 484416 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
la source
$a=new stdClass(); $a->{1} = 1; $b=(array)$a;
get real ['1' => 1].script de magallanes @ PHP 7.3.5
SomeClass Object
est le plus rapide et le plus léger.Array
Vitesse 1,32x . Mémoire 2.70x .stdClass Object
Vitesse 1,65x . Mémoire 2,94x .Sortie brute:
arrays: 0.064794063568115 memory: 444920 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.048975944519043 memory: 164512 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.081161022186279 memory: 484416 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
la source
Pour tous ceux qui sont toujours intéressés par cette question :) J'ai exécuté du code Quazzle sur PHP 7.1 Ubuntu x64 et j'ai obtenu cette réponse:
arrays: 0.24848890304565 memory: 444920 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.23238587379456 memory: 164512 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) arrays: 0.24422693252563 memory: 484416 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
Conclusion
Array prend 4 (!) La mémoire que l'objet de classe.
Objet de classe légèrement plus rapide.
stdClass toujours maléfique © magallanes :)
la source
Vous ne nous avez pas montré le code du
$object->value
fonctionnement, car il se pourrait que le backend soit un tableau auquel cas l' utilisation d'un tableau serait théoriquement plus rapide car elle implique un appel de fonction en moins. Le coût de la recherche sera probablement énorme par rapport à l'appel de fonction. S'il s'agit d'une variable, il y aura très peu de différence car les objets et les tableaux en PHP ont une implémentation très similaire.Si vous recherchez des optimisations, vous devrez établir un profil pour vérifier où la majorité du temps est utilisée. Je soupçonne que changer des objets en tableaux ne fera aucune différence majeure.
la source
Je vois que c'est une sorte de vieux message alors j'ai pensé que je vais le mettre à jour. voici mes codes et statistiques, réalisés sur Zend CE 5.3.21 J'ai essayé de tout tester, en stockant les informations et en les récupérant.
V1: prend 0,83 s
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a[0]; $b = $a[1]; } function get_one() { return array(1,1); }
V2: prend 3,05 s
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { $ret = new test(); $ret->v = 1; $reb->k = 1; return $ret; } class test { public $v; public $k; }
V3: prend 1,98 sec (notez que le constructeur améliore les performances)
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a->v; $b = $a->k; } function get_one() { return new test(1,1); } class test { public $v; public $k; public function __construct($v, $k) { $this->v = $v; $this->k = $k; } }
la source
Vous pouvez toujours vérifier le code source PHP pour des fonctionnalités de micro-performance comme celle-là.
Mais à première vue, ne pas faire ['value'] ne sera pas plus rapide car PHP doit faire une recherche pour savoir où trouver ['value'] même si une recherche de table de hachage devrait être O (1), ce n'est pas garanti. Il y a plus de surcharge lorsque vous utilisez Text-index.
Si l'objet ne contient qu'une seule variable à laquelle vous devez accéder et qui est value, l'utilisation d'un objet est plus lourde.
la source
Eh bien, je suis devenu curieux aujourd'hui en me basant sur le benchmark @magallanes, alors je l'ai un peu développé. J'ai augmenté certaines des boucles for pour vraiment mettre en évidence les écarts entre les choses. Cela fonctionne sur Apache 2.4, mod_php et PHP 7.2.
Voici un tableau récapitulatif pour faciliter les résultats:
+---------------------------+---------+-----------------+ | Test | Memory | Time | +---------------------------+---------+-----------------+ | Array | 2305848 | 9.5637300014496 | | stdClass | 2505824 | 11.212271928787 | | SomeClass | 164920 | 3.9636149406433 | <-- * | AnotherClass | 2563136 | 10.872401237488 | | SetterClass | 905848 | 59.879059791565 | | SetterClassDefineReturn | 905792 | 60.484427213669 | | SetterClassSetFromParam | 745792 | 62.783381223679 | | SetterClassSetKeyAndParam | 745824 | 72.155715942383 | +---------------------------+---------+-----------------+ * - Winner winner chicken dinner
Voici le script modifié. Je voulais tester les propriétés des paramètres avec des méthodes et des types de définition. J'ai été très surpris de constater que l'utilisation des méthodes de setter ajoute un succès significatif au code. Maintenant accordé, il s'agit d'un test de performances très très spécifique où de nombreuses applications n'atteindront même pas cela. Mais si vous avez un site qui gère 1000 / reqs / seconde avec 1000 classes qui sont utilisées avec des milliers d'objets, vous pouvez voir comment cela peut affecter les performances.
<?php set_time_limit(500); class SomeClass { public $aaa; public $bbb; public $ccc; } class AnotherClass { } class SetterClass { public $aaa; public $bbb; public $ccc; public function setAAA() { $this->aaa = 'aaa'; } public function setBBB() { $this->bbb = 'bbb'; } public function setCCC() { $this->ccc = $this->aaa.$this->bbb; } } class SetterClassDefineReturn { public $aaa; public $bbb; public $ccc; public function setAAA():void { $this->aaa = 'aaa'; } public function setBBB():void { $this->bbb = 'bbb'; } public function setCCC():void { $this->ccc = $this->aaa.$this->bbb; } } class SetterClassSetFromParam { public $aaa; public $bbb; public $ccc; public function setAAA(string $val): void { $this->aaa = $val; } public function setBBB(string $val): void { $this->bbb = $val; } public function setCCC(string $val): void { $this->ccc = $val; } } class SetterClassSetKeyAndParam { public $aaa; public $bbb; public $ccc; public function set(string $key, string $val): void { $this->{$key} = $val; } } function p($i) { echo '<pre>'; print_r($i); echo '</pre>'; echo '<hr>'; } $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<1000; $i++) { $z = new SomeClass(); for ($j=0; $j<10000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new AnotherClass(); for ($j=0; $j<5000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new SetterClass(); for ($j=0; $j<5000; $j++) { $z->setAAA(); $z->setBBB(); $z->setCCC(); } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new SetterClassDefineReturn(); for ($j=0; $j<5000; $j++) { $z->setAAA(); $z->setBBB(); $z->setCCC(); } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new SetterClassSetFromParam(); for ($j=0; $j<5000; $j++) { $z->setAAA('aaa'); $z->setBBB('bbb'); $z->setCCC('aaabbb'); } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new SetterClassSetKeyAndParam(); for ($j=0; $j<5000; $j++) { $z->set('aaa', 'aaa'); $z->set('bbb', 'bbb'); $z->set('ccc', 'aaabbb'); } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = new stdClass(); for ($j=0; $j<5000; $j++) { $z->aaa = 'aaa'; $z->bbb = 'bbb'; $z->ccc = $z->aaa.$z->bbb; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z); $t0 = microtime(true); $arraysOf=[]; $inicio=memory_get_usage(); for ($i=0; $i<5000; $i++) { $z = []; for ($j=0; $j<5000; $j++) { $z['aaa'] = 'aaa'; $z['bbb'] = 'bbb'; $z['ccc'] = $z['aaa'].$z['bbb']; } $arraysOf[]=$z; } $fin=memory_get_usage(); echo '<p>Time Taken (seconds): '.(microtime(true) - $t0).'</p>'; echo '<p>Memory: '.($fin-$inicio).'</p>'; p($z);
Et voici les résultats:
Time Taken (seconds): 3.9636149406433 Memory: 164920 SomeClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ----- Time Taken (seconds): 10.872401237488 Memory: 2563136 AnotherClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 59.879059791565 Memory: 905848 SetterClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 60.484427213669 Memory: 905792 SetterClassDefineReturn Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 62.783381223679 Memory: 745792 SetterClassSetFromParam Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 72.155715942383 Memory: 745824 SetterClassSetKeyAndParam Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 11.212271928787 Memory: 2505824 stdClass Object ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb ) ---- Time Taken (seconds): 9.5637300014496 Memory: 2305848 Array ( [aaa] => aaa [bbb] => bbb [ccc] => aaabbb )
la source
Si les tableaux et les classes ont les mêmes performances, je pense que l'utilisation d'objets de classes prédéfinies pour stocker / transmettre des données métier rendrait notre programme plus logique et le code plus lisible.
Aujourd'hui, avec des idées modernes comme Eclipse, Netbean ... il est très pratique de savoir quelles informations un objet (de classe prédéfinie) porte mais les tableaux ne le sont pas
Par exemple: avec tableau
function registerCourse(array $student) { // Right here I don't know how a $student look like unless doing a print_r() or var_dump() .... }
Avec objet
class Studen { private $_name, $_age; public function getAge() {} public function getName() {} .. } function registerCourse(Studen $student) { // Right here I just Ctrl+Space $student or click "Student" and I know I can get name or age from it ... }
la source