Basado en el código de Quazzle, ejecuté el siguiente código (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);
?>
Y obtuve el siguiente resultado:
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
)
Conclusión para php 5.4
- La clase es más rápida que las matrices (pero marginalmente).
- stdClass es malvado.
- La clase usa menos memoria que las matrices. (¡alrededor del 30-40% menos!)
ps: como nota, si la clase está definida pero los miembros entonces, el uso de esta clase es más lento. También usa más memoria. Al parecer el secreto es definir a los miembros
Actualizar
Actualicé de php 5.4 a 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
)
Conclusión para php 5.5
- Para matrices, PHP 5.5 es más rápido que PHP 5.4, para objetos es más o menos lo mismo
- La clase es más lenta que las matrices gracias a la optimización de PHP 5.5 y las matrices.
- stdClass es malvado.
- La clase todavía usa menos memoria que las matrices. (¡¡alrededor del 30-40% menos !!).
- SplFixedArray es similar a usar una clase pero usa más memoria.
Usé este código para "crear perfiles" (1000 instancias, 1000.000 lecturas / escrituras):
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();
Aparece en mi LINUX que aloja estas cosas:
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
así que en conclusión: los objetos son más lentos incluso en PHP 5.2. No uses objetos a menos que realmente necesites sus funciones de oop.
fuente
Yo uso el código de magallanes bajo 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 )
Y el usuario 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 )
fuente
$a=new stdClass(); $a->{1} = 1; $b=(array)$a;
get real ['1' => 1].script de magallanes @ PHP 7.3.5
SomeClass Object
es más rápido y ligero.Array
Velocidad de 1,32x . 2.70x de memoria.stdClass Object
Velocidad de 1,65x . 2.94x de memoria.Salida sin procesar:
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 )
fuente
Para cualquiera que todavía esté interesado en esta pregunta :) Ejecuté el código Quazzle en PHP 7.1 Ubuntu x64 y obtuve esta respuesta:
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 )
Conclusión
Array toma 4 (!) La memoria que el objeto de clase.
Objeto de clase ligeramente más rápido.
stdClass sigue siendo malvado © magallanes :)
fuente
No nos ha mostrado el código de cómo
$object->value
funciona, ya que podría ser que el backend sea una matriz, en cuyo caso, teóricamente, usar una matriz sería más rápido ya que implica una llamada de función menos. El costo de realizar la búsqueda probablemente sea enorme en comparación con la llamada a la función. Si es una variable, habrá muy poca diferencia ya que los objetos y las matrices en PHP tienen una implementación muy similar.Si está buscando optimizaciones, deberá crear un perfil para verificar dónde se está utilizando la mayor parte del tiempo. Sospecho que cambiar objetos por matrices no supondrá una gran diferencia.
fuente
Veo que esta es una publicación antigua, así que pensé en actualizarla. aquí están mis códigos y estadísticas, hechos en Zend CE 5.3.21 Traté de probar todo, almacenando información y retirándola.
V1: tarda 0,83 segundos
for ($i=1; $i<1000000; $i++) { $a = get_one(); $b = $a[0]; $b = $a[1]; } function get_one() { return array(1,1); }
V2: tarda 3,05 segundos
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: tarda 1,98 segundos (tenga en cuenta que el constructor mejora el rendimiento)
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; } }
fuente
Siempre puede consultar el código fuente de PHP para obtener características de micro rendimiento como esa.
Pero a primera vista, no hacer ['valor'] no será más rápido porque PHP necesita hacer una búsqueda sobre dónde encontrar ['valor'] incluso aunque una búsqueda de tabla hash debería ser O (1), eso no está garantizado. Hay más sobrecarga cuando usa Text-index.
Si el objeto solo contiene 1 variable a la que necesita acceder, que es el valor, hay más gastos generales al usar un objeto.
fuente
Bueno, hoy sentí curiosidad por el punto de referencia de @magallanes, así que lo expandí un poco. Subí algunos de los bucles for para resaltar realmente los espacios entre las cosas. Esto se ejecuta en Apache 2.4, mod_php y PHP 7.2.
Aquí hay una tabla de resumen para facilitar los resultados:
+---------------------------+---------+-----------------+ | 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
A continuación se muestra el script modificado. Quería probar las propiedades de configuración con métodos y definir tipos. Me sorprendió mucho descubrir que el uso de métodos de establecimiento agrega un impacto significativo al código. Ahora bien, esta es una prueba de rendimiento muy muy específica en la que muchas aplicaciones ni siquiera lo alcanzarán. Pero si tiene un sitio que maneja 1000 / reqs / second con 1000 clases que se usan con miles de objetos, puede ver cómo esto puede afectar el rendimiento.
<?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);
Y aquí están los resultados:
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 )
fuente
Si las matrices y las clases tienen el mismo rendimiento, creo que usar objetos de clases predefinidas para almacenar / pasar datos comerciales haría que nuestro programa fuera más lógico y el código más legible.
Hoy en día, con ide moderno como Eclipse, Netbean ... es muy conveniente saber qué información lleva un objeto (de clase predefinida) pero las matrices no lo son
Por ejemplo: con matriz
function registerCourse(array $student) { // Right here I don't know how a $student look like unless doing a print_r() or var_dump() .... }
Con objeto
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 ... }
fuente