php - listas - Array asociativo versus SplObjectStorage
listas en php (3)
Estoy trabajando en el código para gestionar una colección de objetos únicos. El primer prototipo de este código utiliza una matriz asociativa, básicamente porque así lo he hecho siempre.
Sin embargo, también estoy interesado en aprovechar la funcionalidad que se ha agregado a las versiones más modernas de PHP como SplObjectStorage para hacer esto en su lugar, en parte como una experiencia de aprendizaje, en parte porque está obligado a ofrecer ventajas (los puntos de referencia que he visto sugieren que SplObjectStorage puede ser más rápido que los arreglos en muchos casos).
La implementación actual tiene una matriz asociativa que verifico con in_array para ver si un objeto ya está en la matriz antes de agregarle un nuevo objeto.
El gran problema que puedo ver con SplObjectStorage es que no parece (a primera vista) admitir el comportamiento de la matriz asociativa clave / valor, y solo se puede tratar como una matriz indexada. Sin embargo, la documentación de las características más recientes de PHP no está a la altura de los estándares de la documentación de partes más establecidas del lenguaje y es posible que simplemente me esté perdiendo algo.
¿Puedo usar SplObjectStorage en lugar de una matriz asociativa? Si es así, ¿cómo defino la clave al agregar un nuevo objeto? Más importante aún, ¿cuáles son las ventajas y desventajas relativas de SplObjectStorage en comparación con matrices asociativas?
Cuando se agote toda la memoria asignada a la matriz, la memoria asignada a ella se duplicará. En este contexto, una colección de objetos puede ser una estructura más efectiva.
Resultados después de ejecutar benchmark con 10000 iteraciones en PHP 5.6.13
:
+------------------+----------------+----------------+---------+
| Type | Time to fill | Time to check | Memory |
+------------------+----------------+----------------+---------+
| SplObjectStorage | 0.021285057068 | 0.019490000000 | 2131984 |
| Array | 0.021125078201 | 0.020912000000 | 1411440 |
+------------------+----------------+----------------+---------+
Como puede ver, los Arrays son 1.5 veces más rápidos que SplObjectStorage
y usan 1.5 veces menos memoria .
No debería ver el SplObjectStorage
como un almacén de valores clave, sino simplemente como un conjunto de objetos . Algo está en el set o no, pero su posición no es importante .
La "clave" de un elemento en el SplObjectStorage
es de hecho el hash del objeto. Hace que no sea posible agregar varias copias de la misma instancia de objeto a un SplObjectStorage
, por lo que no es necesario verificar si ya existe una copia antes de agregarla.
Sin embargo, en PHP 5.4
hay un nuevo método llamado getHash()
que puede anular y devolverá el "hash" del objeto. Esto, en cierto sentido, devuelve / configura la clave para que pueda permitir que se almacene en diferentes condiciones.
La principal ventaja de SplObjectStorage
es el hecho de que obtiene muchos métodos para tratar e interactuar con diferentes conjuntos ( contains()
, removeAll()
, removeAllExcept()
etc. )). Su velocidad es ligeramente mejor, pero el uso de la memoria es peor que los arreglos PHP normales.