Os que odian sempre pisaron PHP por varias razóns, pero un dos obxectivos máis sinxelos é o feo que pode ser o código. Algunhas persoas quizais non estean de acordo en que a limpeza do código e a "boneza" importan, pero cando se trata de manter as bases de código a longo prazo, podes aforrarlle moito tempo ao teu equipo tendo código que sexa fácil de ler.
Mentres estaba en Apple, desenvolvín un ecosistema de aplicacións financeiras utilizadas polas partes interesadas internas. Ao longo dos anos, estiven constantemente incorporando novos desenvolvedores ás ferramentas para axudar co mantemento ou melloras xerais. Unha das principais conclusións daquela época é o importante que é poder ler o teu código cunha linguaxe natural.
É interesante descubrir que a maioría do código está escrito de tal xeito que tes que ler un anaco significativo do mesmo e despois volver ao principio para comprender completamente o que está a suceder. Usar unha linguaxe máis expresiva ou API mentres se escribe código pode reducir en gran medida os tempos de incorporación e aceleración dos novos desenvolvedores.
Aquí é onde brillan as coleccións. As coleccións de Laravel levan algunhas complicadas traxectorias de matriz e fan que sexan incriblemente fáciles de ler e comprender. O teu código convértese nunha cadea de comandos que se len como "Filtra esta matriz só para palabras que comezan por a, despois asigna o importe do custo á fila e, finalmente, redúzao a unha suma de todos os custos". É moi doado subestimar a importancia de escribir o teu código cunha linguaxe máis expresiva, pero unha vez que o fixeches un hábito, é difícil imaxinar como é aceptable calquera outra cousa.
Por suposto, a lexibilidade non pode ser a expensas do rendemento, polo que é importante asegurarnos de que sempre facemos eleccións sólidas e só priorizamos a lexibilidade cando sexa apropiado. Sempre debemos comprender o que está a suceder entre bastidores e ser plenamente conscientes dos compromisos que estamos atopando coa forma en que abordamos as nosas solucións. Non serve de nada que o noso código sexa lexible se leva un segundo máis que unha solución menos lexible.
Mergullémonos e vexamos en profundidade as matrices PHP e as coleccións e comparemos o rendemento entre ambas.
Lexibilidade Coleccións Laravel
Unha das maiores vantaxes de usar Coleccións Laravel é a súa sintaxe fluída, que permite encadear métodos. Isto dá como resultado un código limpo e lexible, xa que pode realizar varias operacións nunha secuencia sen necesidade de variables temporais ou chamadas complexas de funcións aniñadas.
Imos comparar algunhas das funcións de manipulación de matrices de uso común a continuación para ver como PHP se compara coas coleccións nun exemplo moi sinxelo.
Filtro
PHP
array_filter($data, function($row) { return substr($row, 0, 1) === "a"; });
Coleccións
$data->filter(function($row) { return substr($row, 0, 1) === "a"; });
Busca
PHP
array_search(function($row) { return substr($row, 0, 1) === "a"; }, $data);
Coleccións
$data->search(function($row) { return substr($row, 0, 1) === "a"; });
Mapa
PHP
array_map(function($row) { return "test"; }, $data);
Coleccións
$data->map(function($row) { return "test"; });
Ordenar
PHP
sort($data);
Coleccións
$data->sort();
Cada un
PHP
foreach($loop as $item) { $doSomething = true; }
Coleccións
$data->each(function($row) { return "test"; });
Reducir
PHP
array_reduce($data, function($carry, $row) { return $carry + strlen($row); });
Coleccións
$data->reduce(function($carry, $row) { return $carry + strlen($row); });
Empalme
PHP
array_splice($data, count($data)/2);
Coleccións
$data->splice(count($data)/2);
Todos xuntos (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 xuntos (coleccións)
$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
Cun enfoque tan sinxelo, non parece haber unha gran compensación na lexibilidade para cada función individual, aínda que cando consideras o exemplo no que necesitas que todos se apliquen a unha única matriz, podes ver claramente que é máis conciso e máis fácil de ler cando se usan os métodos encadeados nunha colección.
En lugar de ter que sobrescribir constantemente a súa variable e despois establecer unha nova variable para a saída ao final, podemos simplemente encadear todos os comandos ata chegar á saída desexada. As coleccións son sen dúbida máis fáciles de ler canto máis complexo se fai o teu código.
Rendemento
Tomei os exemplos anteriores e xerei algúns datos de proba para tentar determinar se as coleccións tiñan máis ou menos rendemento que as funcións estándar de PHP.
Cada matriz tiña 100.000 cadeas aleatorias como elementos, e executei cada función 100 veces. Ao final, calculamos a media de todos os tempos de resposta.
Os resultados finais son os seguintes:
========== 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 =======================
Conclusión
Como podes ver claramente, aínda que gañamos unha gran lexibilidade das coleccións, perdemos unha cantidade significativa de rendemento nalgunhas áreas clave.
Filter , Map , Foreach e Reduce son todos máis rápidos coas funcións estándar de PHP. Foreach e Reduce son realmente diferenzas incriblemente significativas. Busca , Ordenar e Empalme mostran todas as coleccións como gañadoras, e Ordenar é realmente un aforro de tempo enorme.
Tamén é importante ter en conta que terías que crear cada colección a partir dunha matriz construída que engade un pouco de sobrecarga para configurar a colección para comezar, pero aínda con esa pequena cantidade de traballo e tempo extra, os resultados son bastante claro.
Na miña opinión (e é só unha opinión baseada nestes resultados), se o rendemento é unha gran preocupación, seguiríame coa funcionalidade estándar de PHP para bucles Foreach con certeza e probablemente o mesmo para calquera necesidade de Reduce . Se precisa facer algunha clasificación en conxuntos de datos grandes, é evidente que Coleccións é o camiño correcto. O resto está tan preto que realmente parece unha preferencia persoal.
Nese momento, diría que as coleccións sempre son máis fáciles de ler e manter.
Obviamente, deberías tomar esta información e tomar a túa propia decisión informada, non obstante, se es coma min, creo que te atoparás facendo coleccións para moitas destas funcións anteriores. Pero creo que vou recuperar o meu uso de →each
e →reduce
cando corresponda no futuro!