Izabrani projekti
php-llamacpp-benchmarks
Šest llama.cpp-inspirisanih optimizacionih obrazaca prevedenih u idiomatski PHP 8.4 sa JIT-om, plus naive-vs-optimised importer CSV → Postgres. Reproducibilno preko Docker + Make.
- PHP 8.4
- llama.cpp
- FFI
- JIT
- Docker
- PostgreSQL 16
- PHPStan L8
Zašto ovo postoji
llama.cpp je jedan od najagresivnije optimizovanih C/C++ kodbejzova u aktivnom razvoju. Mmap weight-ovi, ravni dense baferi, value pool-ovi, table dispatch, token streaming, columnar layout-i — svaki cache line i svaka alokacija pod kontrolom. Većina tih alata je u teoriji jezik-agnostična. Otud iskreno pitanje: koliko od toga preživi prevod u PHP 8.4 sa JIT-om i šta svaki obrazac zaista donosi?
Ovaj repozitorijum odgovara brojevima. Šest mikro benchmark-a plus jedan realističan case study, sve reproducibilno preko docker compose i Makefile-a. Prateći Medium tekst — I Scaled PHP Until It Broke. Three llama.cpp Patterns Saved It. — prolazi kroz pobede i poraze.
Šta je u suite-u
| ID | Tehnika | Šta se meri |
|---|---|---|
| B01 | FFI mmap | tabela od 10M zapisa: load time, heap, lookup p50/p95/p99, cross-process cold start |
| B02 | SplFixedArray | 10M int-ova: memorija, popunjavanje, pun obilazak, random R/W |
| B03 | Object pool | 5M Point3D alokacija vs reused pool, GC delta |
| B04 | Lookup-tabela vs match vs switch | 10M klasifikacija, tri implementacije jedna pored druge |
| B05 | Generator | 5M zapisa: materijalizovan niz vs streaming, peak memory |
| B06 | Column- vs row-oriented | 5M zapisa × 5 polja: single-column scan + full-row scan |
Svaki run je warmup → measured iterations → hrtime(true) → memory_get_peak_usage(true) → percentili kroz linearnu interpolaciju. Pobeda od 1.2× se prikazuje kao 1.2×. Bez kuvanja.
End-to-end case study
bin/run-case-study.php pokreće dva importer-a nad istim CSV-om od 100K redova i istom Postgres tabelom:
- Naive importer — pun CSV u niz,
new Record()po redu, assoc-array dedupe, JSON-učitan country map, single-row INSERT-i. - Optimised importer — Generator CSV reader (B05), pooled Record (B03), SplFixedArray-backed dedupe sa linear probing (B02), mmap-ovana binarna country tabela (B01), multi-VALUES INSERT od 1000 redova.
Šest obrazaca, jedno realistično opterećenje. Poenta nije jedan herojski broj — već da se vidi koji obrazac se isplati, a koji je prekomeran.
Honesty notes
- Benchmark-i se izvršavaju u Docker-u (
php:8.4-cli-bookworm, opcache + JIT). Pokrenite suite više puta — prvi run-ovi su uvek bučniji. - B01 meri warm load time (kernel page cache zagrejan). Stvarni cold-disk brojevi zavise od storage-a i van su scope-a in-process benchmark-a.
- B03 pobeda na one-shot CLI je obično skromna. Obrazac se pokazuje u long-running worker-ima (queue-ovi, websocket-i).
- B04 može dati manju pobedu nego što C intuicija predviđa: JIT u PHP 8.3 kompajlira
matchveoma dobro. Tekst to razmatra.
Šta dobijaš kada kloniraš
make build # build PHP image-a (jednom)
make all # install, fixtures, db, bench, case-study
Rezultat: results/results.md i results/results.json sa p50/p95/p99 po benchmark-u, peak memory i hash commit-a. Zakači na CI i prati kako brojevi drift-uju kroz vreme.