La SPL de PHP incluye estructuras de datos más especializadas para casos donde el rendimiento en memoria o el tiempo de acceso importan. SplFixedArray crea arrays de tamaño fijo que consumen significativamente menos memoria que los arrays asociativos normales de PHP. SplMinHeap, SplMaxHeap y SplPriorityQueue implementan colas de prioridad con inserción y extracción en tiempo O(log n).
SplFixedArray: arrays de tamaño fijo
Un array PHP normal es una tabla hash que gestiona memoria dinámicamente. SplFixedArray usa un array de C de tamaño fijo por debajo, lo que puede consumir hasta cuatro veces menos memoria al trabajar con grandes colecciones de enteros o valores simples.
<?php
// Array PHP normal con 1.000.000 de enteros
$array = range(0, 999999);
echo memory_get_usage(true) / 1024 / 1024; // ~32 MB
// SplFixedArray con 1.000.000 de enteros
$fixed = new SplFixedArray(1000000);
for ($i = 0; $i < 1000000; $i++) {
$fixed[$i] = $i;
}
echo memory_get_usage(true) / 1024 / 1024; // ~8 MB (aprox 4x menos)
// Solo acepta índices enteros no negativos dentro del rango
echo $fixed[0]; // 0
echo $fixed[999999]; // 999999
// $fixed[1000000] // RuntimeException: out of bounds
// Tamaño fijo: no se puede hacer push ni pop
echo $fixed->getSize(); // 1000000
// Convertir desde/hacia array normal
$normal = $fixed->toArray();
$nuevo = SplFixedArray::fromArray([1, 2, 3, 4, 5]);
?>
SplMinHeap: cola de prioridad mínima
Un heap (montículo) es una estructura de árbol que garantiza que el nodo raíz siempre es el menor (min-heap) o el mayor (max-heap) de todos los elementos. La inserción y extracción son O(log n), mucho más eficientes que ordenar un array en cada operación.
<?php
$minHeap = new SplMinHeap();
$minHeap->insert(15);
$minHeap->insert(3);
$minHeap->insert(9);
$minHeap->insert(1);
$minHeap->insert(7);
// extract() devuelve y elimina el elemento más pequeño
while (!$minHeap->isEmpty()) {
echo $minHeap->extract() . ' ';
}
// Salida: 1 3 7 9 15 (orden ascendente)
// top() devuelve el mínimo sin extraerlo
$heap = new SplMinHeap();
$heap->insert(5);
$heap->insert(2);
$heap->insert(8);
echo $heap->top(); // 2 (sin extraer)
?>
SplMaxHeap: cola de prioridad máxima
<?php
$maxHeap = new SplMaxHeap();
$maxHeap->insert(15);
$maxHeap->insert(3);
$maxHeap->insert(9);
$maxHeap->insert(1);
$maxHeap->insert(7);
while (!$maxHeap->isEmpty()) {
echo $maxHeap->extract() . ' ';
}
// Salida: 15 9 7 3 1 (orden descendente)
// Caso práctico: obtener los 3 ficheros más grandes de un directorio
$heap = new SplMaxHeap();
foreach (new FilesystemIterator('/var/log') as $fichero) {
if ($fichero->isFile()) {
$heap->insert($fichero->getSize());
}
}
$top3 = [];
for ($i = 0; $i < 3 && !$heap->isEmpty(); $i++) {
$top3[] = $heap->extract();
}
// $top3 contiene los tres tamaños mayores
?>
SplPriorityQueue: cola con prioridad explícita
SplPriorityQueue permite asociar una prioridad numérica a cada elemento. Los elementos con mayor prioridad se extraen primero. Cuando dos elementos tienen la misma prioridad, el orden de extracción es indefinido.
<?php
$cola = new SplPriorityQueue();
// insert(dato, prioridad): mayor prioridad = sale antes
$cola->insert(['tarea' => 'enviar_email', 'urgencia' => 'baja'], 1);
$cola->insert(['tarea' => 'pago_pendiente', 'urgencia' => 'alta'], 10);
$cola->insert(['tarea' => 'generar_informe', 'urgencia' => 'media'], 5);
$cola->insert(['tarea' => 'alerta_seguridad', 'urgencia' => 'critica'], 100);
// Por defecto extract() solo devuelve el dato, no la prioridad
$cola->setExtractFlags(SplPriorityQueue::EXTR_BOTH); // devuelve ['data' => ..., 'priority' => ...]
while (!$cola->isEmpty()) {
$item = $cola->extract();
echo $item['data']['tarea'] . " (prioridad: {$item['priority']})n";
}
// alerta_seguridad (prioridad: 100)
// pago_pendiente (prioridad: 10)
// generar_informe (prioridad: 5)
// enviar_email (prioridad: 1)
?>
La documentación oficial de SplFixedArray incluye los benchmarks de memoria, y la de SplHeap detalla cómo extender la clase para definir criterios de comparación personalizados mediante el método compare().
