Os haters sempre pisaram no PHP por uma variedade de razões, mas um dos alvos mais fáceis é o quão feio o código pode ser. Algumas pessoas podem não concordar que a limpeza e a “beleza” do código importam, mas quando se trata de manter bases de código a longo prazo, você pode economizar muito tempo para sua equipe tendo um código que seja fácil de ler.
Enquanto estava na Apple, desenvolvi um ecossistema de aplicativos financeiros usados por stakeholders internos. Ao longo dos anos, eu estava constantemente integrando novos desenvolvedores nas ferramentas para auxiliar na manutenção geral ou melhorias. Uma das principais lições daquela época é o quão importante é ser capaz de ler seu código com linguagem natural.
É interessante descobrir que a maioria dos códigos é escrita de tal forma que você tem que ler um pedaço significativo dele e depois voltar ao início para entender completamente o que está acontecendo. Usar uma linguagem ou APIs mais expressivas ao escrever código pode reduzir muito os tempos de integração e ramp-up de novos desenvolvedores.
É aqui que as Coleções brilham. As Coleções do Laravel pegam algumas travessias de array complicadas e as tornam incrivelmente fáceis de ler e entender. Seu código se torna uma cadeia de comandos lida como "Filtre este array para apenas palavras que começam com a, então mapeie o valor do custo para a linha e, por último, reduza isso para uma soma de todos os custos". É muito fácil subestimar a importância de escrever seu código com uma linguagem mais expressiva, mas uma vez que você tenha feito disso um hábito, é difícil imaginar como qualquer outra coisa é aceitável.
Claro, a legibilidade não pode vir às custas do desempenho, então é importante garantir que estamos sempre fazendo escolhas sensatas e priorizando a legibilidade somente onde for apropriado. Devemos sempre entender o que está acontecendo nos bastidores e estar totalmente cientes de quais compensações estamos encontrando com a maneira como abordamos nossas soluções. Não adianta nada que nosso código seja legível se ele levar um segundo inteiro a mais do que uma solução menos legível.
Vamos nos aprofundar e dar uma olhada mais aprofundada em arrays PHP vs. coleções e comparar o desempenho entre os dois.
Legibilidade Coleções Laravel
Uma das maiores vantagens de usar Laravel Collections é sua sintaxe fluente, que permite encadear métodos. Isso resulta em um código limpo e legível, pois você pode executar várias operações em uma sequência sem precisar de variáveis temporárias ou chamadas de funções aninhadas complexas.
Vamos comparar algumas das funções de manipulação de array comumente usadas abaixo para ver como o PHP se compara às Coleções em um exemplo muito simples.
Filtro
PHP
array_filter($data, function($row) { return substr($row, 0, 1) === "a"; });
Coleções
$data->filter(function($row) { return substr($row, 0, 1) === "a"; });
Procurar
PHP
array_search(function($row) { return substr($row, 0, 1) === "a"; }, $data);
Coleções
$data->search(function($row) { return substr($row, 0, 1) === "a"; });
Mapa
PHP
array_map(function($row) { return "test"; }, $data);
Coleções
$data->map(function($row) { return "test"; });
Organizar
PHP
sort($data);
Coleções
$data->sort();
Cada
PHP
foreach($loop as $item) { $doSomething = true; }
Coleções
$data->each(function($row) { return "test"; });
Reduzir
PHP
array_reduce($data, function($carry, $row) { return $carry + strlen($row); });
Coleções
$data->reduce(function($carry, $row) { return $carry + strlen($row); });
Emenda
PHP
array_splice($data, count($data)/2);
Coleções
$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 (Coleções)
$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); });
Comparação
Com uma abordagem tão simples, não parece haver uma grande troca na legibilidade de cada função individual, embora quando você considera o exemplo em que precisa que todas elas sejam aplicadas a uma única matriz, você pode ver claramente que é mais conciso e fácil de ler ao usar os métodos encadeados em uma coleção.
Em vez de ter que sobrescrever constantemente sua variável e então definir uma nova variável para saída no final, podemos simplesmente encadear cada comando até chegarmos à saída desejada. As coleções são definitivamente mais fáceis de ler quanto mais complexo seu código se torna.
Desempenho
Peguei os exemplos acima e gerei alguns dados de teste para tentar determinar se as coleções tinham mais ou menos desempenho do que as funções PHP padrão.
Cada array tinha 100.000 strings aleatórias como itens, e eu executei cada função 100 vezes. No final, calculamos a média de todos os tempos de resposta.
Os resultados finais estão abaixo:
========== 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 =======================
Conclusão
Como você pode ver claramente, embora ganhemos uma grande quantidade de legibilidade com as Coleções, perdemos uma quantidade significativa de desempenho em algumas áreas importantes.
Filter , Map , Foreach e Reduce são todos mais rápidos com as funções PHP padrão. Foreach e Reduce são, na verdade, diferenças incrivelmente significativas. Search , Sort e Splice mostram Collections como o vencedor, e Sort é, na verdade, uma grande economia de tempo.
Também é importante observar que você teria que criar cada coleção a partir de uma matriz construída, o que acrescenta um pouco de sobrecarga à configuração inicial da coleção, mas mesmo com essa pequena quantidade de trabalho e tempo extra, os resultados são bem claros.
Na minha opinião (e é apenas uma opinião baseada nesses resultados), se o desempenho for uma grande preocupação, eu ficaria com a funcionalidade PHP padrão para loops Foreach com certeza e provavelmente o mesmo para quaisquer necessidades de Reduce . Se você precisa fazer qualquer classificação em grandes conjuntos de dados, claramente Collections é o caminho certo a seguir. O resto é tão próximo que realmente parece uma preferência pessoal.
Nesse ponto, eu diria que as coleções são sempre mais fáceis de ler e manter.
Obviamente, você deve pegar essas informações e tomar sua própria decisão informada, no entanto, se você for como eu, acho que você vai acabar inserindo coleções para muitas dessas funções acima. Mas acho que vou diminuir meu uso de →each
e →reduce
quando apropriado daqui para frente!