Šta zapravo košta učitavanje celog lib/
U ovom članku
Linija 46 jedine ulazne datoteke ovog servisa:
foreach (glob(__DIR__ . '/lib/*.php') as $f) { require_once $f; }
To je 65 datoteka i 1,5 megabajta, učitano pri svakom zahtevu. Slika brojača, statistička stranica, 404 — sve isto. Juče se to desilo 20.734 puta.
Broj koji je važan je onaj mali
Učitavanje svega od nule, sa isključenim kešom opkodova, traje oko 132 milisekunde. To je broj zbog kog bi ovo bio problem i nije broj koji server plaća.
Sa opkodovima već kompajliranim i držanim u deljenoj memoriji, ostaju samo listanje direktorijuma i jedan stat() po datoteci, jer je uključena provera vremenske oznake: 0,33 milisekunde. Pri jučerašnjem saobraćaju to je manje od sedam sekundi posla tokom celog dana.
Između je treće merenje, 18,2 milisekunde, uzeto sa kešom opkodova koji čita sa diska umesto iz memorije. To je gornja granica, a ne stvarna brojka — to je ono što se dešava kada keš postoji ali je sporiji od pravog. Prijavljeno je jer je to jedini topli broj koji se može izmeriti iz komandne linije, a pretvarati se da nije bila bi laka greška.
Dakle: ovo košta skoro ništa, i košta skoro ništa u potpunosti zbog nečeg drugog. Isključite keš opkodova i ista linija košta četiri stotine puta više. To je stvarna zavisnost, i vredi znati da postoji umesto da se otkrije tokom nadogradnje.
Šta je zapravo u tih 1,5 megabajta
Četrdeset sedam odsto toga — 715 kilobajta u 26 datoteka — porodice su dizajna brojača. Za crtanje slike brojača treba tačno jedna od njih. Ostalih 25 se učitava, deklariše i nikada ne dotakne.
Posle toga: 189 kilobajta podataka o zastavama, potrebnih na stranici geografije; 158 kilobajta biblioteke za grafikone, potrebnih kada nešto crta grafikon. Nijedno ne učestvuje u služenju slike brojača, što je zahtev na koji ovaj servis odgovara češće nego na bilo koji drugi.
Vidljiva cena toga je pre memorija nego vreme. Vršna memorija po zahtevu raste za oko četiri megabajta, i za razliku od opkodova — koji se dele među svim procesima — taj deo se plaća po zahtevu, paralelno, od svakog radnika odjednom.
Neko je to već primetio
Glob je lib/*.php. Nije rekurzivan, a neposredno ispod njega nalaze se dva direktorijuma: lib/live/ sa 229 kilobajta i lib/recht/ sa 182 kilobajta. Četiristo kilobajta koji su nekad bili na putanji učitavanja, a sada nisu.
Premešteni su jer su veliki i retko potrebni: statistički odeljci i pravni tekstovi. Jedan direktorijum dublje je ceo mehanizam. Nema konfiguracije, nema lenjog učitavača, nema mape automatskog učitavanja — datoteka je ili u globu ili nije.
To je stvarna popravka i vredi to reći, jer bi očigledan sledeći korak bio autoloader, a autoloader bi ovde bio velika izmena da se reši problem koji je mkdir već dvaput rešio.
Zašto ostaje
Jedan glob je najjednostavnija stvar koja može da radi, i prema dokazima radi: trećina milisekunde, na malom serveru, na putanji koja mora da bude brza. Zamena pojedinačnim require-ovima znači da svaka nova datoteka traži liniju negde, a linija koja se zaboravi proizvodi fatalnu grešku u produkciji umesto malo većeg učitavanja.
Ono što joj treba jeste upravo ono što ju je učinilo podnošljivom na početku, zapisano: ako datoteka u lib/ postane velika, prelazi u poddirektorijum i uključuje se tamo gde se koristi. To je pravilo po kome su se ta dva direktorijuma ponašala, a do sada nije bilo zapisano nigde.
Opšta verzija je dosadnija od merenja. „Sve učitava sve“ obično je pogrešan oblik i vredi izmeriti šta košta pre nego što se prepravi. Ovde košta 0,33 milisekunde i četiri megabajta, a četiri megabajta su deo koji vredi pratiti, jer rastu sa istovremenošću, a milisekunde ne.