Los detractores siempre han criticado a PHP por diversas razones, pero uno de los blancos más fáciles es lo feo que puede ser el código. Es posible que algunas personas no estén de acuerdo con que la limpieza y la "belleza" del código sean importantes, pero cuando se trata de mantener bases de código a largo plazo, puede ahorrarle mucho tiempo a su equipo si tiene un código que sea fácil de leer.
Mientras trabajé en Apple, desarrollé un ecosistema de aplicaciones financieras que utilizaban las partes interesadas internas. A lo largo de los años, incorporé constantemente nuevos desarrolladores a las herramientas para ayudar con el mantenimiento general o las mejoras. Una de las principales conclusiones de esa época es lo importante que es poder leer el código con lenguaje natural.
Es interesante descubrir que la mayor parte del código está escrito de tal manera que es necesario leer una parte importante del mismo y luego volver al principio para comprender completamente lo que está sucediendo. El uso de un lenguaje más expresivo o de API al escribir código puede reducir en gran medida los tiempos de incorporación y puesta en marcha de los nuevos desarrolladores.
Aquí es donde las colecciones brillan. Las colecciones de Laravel toman algunos recorridos de matriz complicados y los hacen increíblemente fáciles de leer y comprender. Su código se convierte en una cadena de comandos que se lee como "Filtre esta matriz solo con palabras que comiencen con a, luego asigne el monto del costo a la fila y, por último, reduzca esto a una suma de todos los costos". Es muy fácil subestimar la importancia de escribir su código con un lenguaje más expresivo, pero una vez que lo ha convertido en un hábito, es difícil imaginar que cualquier otra cosa sea aceptable.
Por supuesto, la legibilidad no puede ir en detrimento del rendimiento, por lo que es importante garantizar que siempre tomamos decisiones acertadas y priorizamos la legibilidad solo cuando sea apropiado. Siempre debemos comprender lo que sucede detrás de escena y ser plenamente conscientes de las desventajas que enfrentamos con la forma en que abordamos nuestras soluciones. No sirve de nada que nuestro código sea legible si tarda un segundo más que una solución menos legible.
Vamos a analizar en profundidad las matrices y colecciones de PHP y comparar el rendimiento entre ambos.
Una de las mayores ventajas de usar colecciones de Laravel es su sintaxis fluida, que permite encadenar métodos. Esto da como resultado un código limpio y legible, ya que puedes realizar múltiples operaciones en una secuencia sin necesidad de variables temporales o llamadas de funciones anidadas complejas.
A continuación, comparemos algunas de las funciones de manipulación de matrices más utilizadas para ver cómo se compara PHP con las colecciones en un ejemplo muy simple.
PHP
array_filter($data, function($row) { return substr($row, 0, 1) === "a"; });
Colecciones
$data->filter(function($row) { return substr($row, 0, 1) === "a"; });
PHP
array_search(function($row) { return substr($row, 0, 1) === "a"; }, $data);
Colecciones
$data->search(function($row) { return substr($row, 0, 1) === "a"; });
PHP
array_map(function($row) { return "test"; }, $data);
Colecciones
$data->map(function($row) { return "test"; });
PHP
sort($data);
Colecciones
$data->sort();
PHP
foreach($loop as $item) { $doSomething = true; }
Colecciones
$data->each(function($row) { return "test"; });
PHP
array_reduce($data, function($carry, $row) { return $carry + strlen($row); });
Colecciones
$data->reduce(function($carry, $row) { return $carry + strlen($row); });
PHP
array_splice($data, count($data)/2);
Colecciones
$data->splice(count($data)/2);
Todos juntos (PHP)
$data = array_filter($data, function($row) { return substr($row, 0, 1) === "a"; }); $data = array_search(function($row) { return substr($row, 0, 1) === "a"; }, $data); $data = array_map(function($row) { return "test"; }, $data); sort($data); foreach($loop as $item) { $doSomething = true; } $sum = array_reduce($data, function($carry, $row) { return $carry + strlen($row); });
Todos juntos (Colecciones)
$sum = $data->filter(function($row) { return substr($row, 0, 1) === "a"; })->search(function($row) { return substr($row, 0, 1) === "a"; })->map(function($row) { return "test"; })->sort() ->each(function($row) { return "test"; })->reduce(function($carry, $row) { return $carry + strlen($row); });
Comparación
Con un enfoque tan simple, no parece haber una gran desventaja en cuanto a legibilidad para cada función individual, aunque cuando se considera el ejemplo donde se necesita que todas se apliquen a una sola matriz, se puede ver claramente que es más conciso y más fácil de leer cuando se usan los métodos encadenados en una colección.
En lugar de tener que sobrescribir constantemente la variable y luego configurar una nueva variable para la salida al final, podemos simplemente encadenar cada comando hasta que obtengamos la salida deseada. Las colecciones son definitivamente más fáciles de leer cuanto más complejo se vuelve el código.
Tomé los ejemplos anteriores y generé algunos datos de prueba para intentar determinar si las colecciones tenían más o menos rendimiento que las funciones PHP estándar.
Cada matriz tenía 100.000 cadenas aleatorias como elementos y ejecuté cada función 100 veces. Al final, calculamos el promedio de todos los tiempos de respuesta.
Los resultados finales son los siguientes:
========== Tests Complete (ms) ========== php filter: 5.07 collect filter: 6.49 ======================= php search: 0.79 collect search: 0 ======================= php map: 3.45 collect map: 4.18 ======================= php sort: 25.27 collect sort: 11.18 ======================= php each: 1.03 collect each: 6.96 ======================= php reduce: 2.78 collect reduce: 7.75 ======================= php splice: 1 collect splice: 0.74 =======================
Como puede ver claramente, si bien ganamos una gran cantidad de legibilidad con las colecciones, perdemos una cantidad significativa de rendimiento en algunas áreas clave.
Filter , Map , Foreach y Reduce son todas más rápidas con las funciones estándar de PHP. Foreach y Reduce son en realidad diferencias increíblemente significativas. Search , Sort y Splice muestran que Collections es la ganadora, y Sort es en realidad un gran ahorro de tiempo.
También es importante tener en cuenta que tendría que crear cada colección a partir de una matriz construida, lo que agrega un poco de sobrecarga a la configuración de la colección para empezar, pero incluso con esa pequeña cantidad de trabajo y tiempo adicionales, los resultados son bastante claros.
En mi opinión (y es solo una opinión basada en estos resultados), si el rendimiento es una gran preocupación, me quedaría con la funcionalidad estándar de PHP para los bucles Foreach con seguridad y probablemente lo mismo para cualquier necesidad de Reduce . Si necesita realizar cualquier ordenación en grandes conjuntos de datos, claramente Collections es el camino correcto a seguir. El resto son tan similares que realmente parece una preferencia personal.
En ese punto, diría que las colecciones siempre son más fáciles de leer y mantener.
Obviamente, debes tomar esta información y tomar tu propia decisión informada; sin embargo, si eres como yo, creo que te encontrarás introduciendo colecciones para muchas de las funciones mencionadas anteriormente. ¡Pero creo que reduciré el uso de →each
y →reduce
cuando sea apropiado de ahora en adelante!