Palaging tinatapakan ng mga haters ang PHP para sa iba't ibang dahilan, ngunit ang isa sa pinakamadaling target ay kung gaano kapangit ang code. Maaaring hindi sumang-ayon ang ilang tao na mahalaga ang kalinisan ng code at "kagandahan", ngunit pagdating sa pagpapanatili ng mga codebase para sa mahabang panahon, makakatipid ka ng maraming oras sa iyong team sa pamamagitan ng pagkakaroon ng code na madaling basahin.
Habang nasa Apple, bumuo ako ng ecosystem ng mga aplikasyon sa pananalapi na ginagamit ng mga internal na stakeholder. Sa paglipas ng mga taon, palagi akong naglalagay ng mga bagong developer sa mga tool para tumulong sa pangkalahatang pagpapanatili o mga pagpapahusay. Isa sa mga pangunahing takeaways mula sa oras na iyon ay kung gaano kahalaga na mabasa ang iyong code gamit ang natural na wika.
Nakatutuwang malaman na karamihan sa code ay nakasulat sa paraang kailangan mong basahin ang isang makabuluhang bahagi nito, pagkatapos ay bumalik sa simula upang lubos na maunawaan kung ano ang nangyayari. Ang paggamit ng mas makahulugang wika o mga API habang nagsusulat ng code ay maaaring lubos na mabawasan ang mga oras ng onboarding at ramp-up ng mga bagong developer.
Dito nagniningning ang Mga Koleksyon. Ang Laravel Collections ay kumukuha ng ilang kumplikadong array traversal at ginagawa itong napakadaling basahin at maunawaan. Ang iyong code ay nagiging isang hanay ng mga command na kababasahan tulad ng "I-filter ang array na ito sa mga salita lamang na nagsisimula sa a, pagkatapos ay i-map ang halaga ng gastos sa row, at sa wakas ay bawasan ito sa kabuuan ng lahat ng mga gastos." Napakadaling i-undersell ang kahalagahan ng pagsulat ng iyong code na may mas nagpapahayag na wika, ngunit kapag nakagawian mo na ito, mahirap isipin kung paano katanggap-tanggap ang anumang bagay.
Siyempre, ang pagiging madaling mabasa ay hindi maaaring maging sanhi ng pagganap kaya mahalagang tiyakin na palagi kaming gumagawa ng mga tamang pagpipilian at inuuna lang ang pagiging madaling mabasa kung saan ito naaangkop. Dapat nating palaging maunawaan kung ano ang nangyayari sa likod ng mga eksena at ganap na magkaroon ng kamalayan sa kung anong mga tradeoff ang nararanasan natin sa paraan ng paglapit natin sa ating mga solusyon. Hindi mabuti para sa aming code na maging nababasa kung ito ay tumatagal ng isang buong segundo na mas mahaba kaysa sa isang hindi gaanong nababasa na solusyon.
Sumisid tayo at tingnan nang malalim ang mga array ng PHP kumpara sa Mga Koleksyon at ihambing ang pagganap sa pagitan ng dalawa.
Mga Koleksyon ng Laravel sa pagiging madaling mabasa
Ang isa sa pinakamalaking bentahe ng paggamit ng Laravel Collections ay ang kanilang matatas na syntax, na nagbibigay-daan para sa mga paraan ng pag-chain. Nagreresulta ito sa malinis at nababasang code, dahil maaari kang magsagawa ng maraming operasyon sa isang pagkakasunud-sunod nang hindi nangangailangan ng mga pansamantalang variable o kumplikadong nested function na tawag.
Ihambing natin ang ilan sa mga karaniwang ginagamit na function ng pagmamanipula ng array sa ibaba upang makita kung paano inihahambing ang PHP sa Mga Koleksyon sa isang napakasimpleng halimbawa.
Salain
PHP
array_filter($data, function($row) { return substr($row, 0, 1) === "a"; });
Mga koleksyon
$data->filter(function($row) { return substr($row, 0, 1) === "a"; });
Maghanap
PHP
array_search(function($row) { return substr($row, 0, 1) === "a"; }, $data);
Mga koleksyon
$data->search(function($row) { return substr($row, 0, 1) === "a"; });
Mapa
PHP
array_map(function($row) { return "test"; }, $data);
Mga koleksyon
$data->map(function($row) { return "test"; });
Pagbukud-bukurin
PHP
sort($data);
Mga koleksyon
$data->sort();
Ang bawat isa
PHP
foreach($loop as $item) { $doSomething = true; }
Mga koleksyon
$data->each(function($row) { return "test"; });
Bawasan
PHP
array_reduce($data, function($carry, $row) { return $carry + strlen($row); });
Mga koleksyon
$data->reduce(function($carry, $row) { return $carry + strlen($row); });
Magdugtong
PHP
array_splice($data, count($data)/2);
Mga koleksyon
$data->splice(count($data)/2);
All Together (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); });
Lahat ng Sama-sama (Mga Koleksyon)
$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); });
Paghahambing
Sa ganitong simpleng diskarte, mukhang walang malaking tradeoff sa pagiging madaling mabasa para sa bawat indibidwal na function, bagama't kapag isinasaalang-alang mo ang halimbawa kung saan kailangan mong ilapat ang lahat sa iisang array, malinaw mong makikita na ito ay higit pa maikli at mas madaling basahin kapag ginagamit ang mga chained-methods sa isang koleksyon.
Sa halip na patuloy na kailangang i-overwrite ang iyong variable at pagkatapos ay magtakda ng bagong variable para sa output sa dulo, maaari lang nating i-chain ang bawat command hanggang sa makuha natin ang gusto nating output. Talagang mas madaling basahin ang mga koleksyon kapag nagiging mas kumplikado ang iyong code.
Pagganap
Kinuha ko ang mga halimbawa sa itaas at nakabuo ng ilang data ng pagsubok upang subukang matukoy kung ang mga koleksyon ay higit pa o hindi gaanong gumaganap kaysa sa karaniwang mga function ng PHP.
Ang bawat array ay mayroong 100,000 random na mga string bilang mga item, at pinatakbo ko ang bawat function ng 100 beses. Sa huli, kinakalkula namin ang average ng lahat ng oras ng pagtugon.
Ang mga huling resulta ay nasa ibaba:
========== 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 =======================
Konklusyon
Gaya ng malinaw mong nakikita, kahit na nakakakuha kami ng malaking halaga ng pagiging madaling mabasa mula sa Mga Koleksyon, nawalan kami ng malaking halaga ng pagganap sa ilang mahahalagang bahagi.
Ang Filter , Map , Foreach , at Reduce ay lahat ng mas mabilis gamit ang karaniwang mga function ng PHP. Ang Foreach at Reduce ay talagang hindi kapani-paniwalang makabuluhang pagkakaiba. Ang Search , Sort , at Splice ay nagpapakita ng lahat ng Collections bilang panalo, at ang Sort ay talagang isang napakalaking time saver.
Mahalaga rin na tandaan na kailangan mong lumikha ng bawat koleksyon mula sa isang built array na nagdaragdag ng kaunting overhead sa pag-set up ng koleksyon upang magsimula, ngunit kahit na may maliit na halaga ng karagdagang trabaho at oras, ang mga resulta ay medyo malinaw.
Sa aking opinyon (at ito ay isang opinyon lamang batay sa mga resultang ito), kung ang pagganap ay isang malaking pag-aalala, mananatili ako sa karaniwang pag-andar ng PHP para sa Foreach loop para sigurado at malamang na pareho para sa anumang mga pangangailangan sa Bawasan . Kung kailangan mong gumawa ng anumang pag-uuri sa malalaking dataset, malinaw na Koleksyon ang tamang paraan. Ang natitira ay napakalapit na ito ay talagang parang isang personal na kagustuhan.
Sa puntong iyon, masasabi kong ang mga koleksyon ay palaging mas madaling basahin at mapanatili.
Malinaw, dapat mong kunin ang impormasyong ito at gumawa ng iyong sariling matalinong pagpapasya, gayunpaman, kung ikaw ay tulad ko, sa palagay ko ay makikita mo ang iyong sarili na kumukuha ng mga koleksyon para sa marami sa mga function na ito sa itaas. Ngunit sa palagay ko ay idi-dial ko muli ang aking paggamit ng →each
at →reduce
kung saan naaangkop pasulong!