Berapa sebenarnya biaya memuat seluruh lib/
Baris 46 di satu-satunya berkas titik masuk layanan ini:
foreach (glob(__DIR__ . '/lib/*.php') as $f) { require_once $f; }
Itu berarti 65 berkas dan 1,5 megabyte, dimuat pada setiap permintaan. Gambar penghitung, halaman statistik, halaman 404 — semuanya sama. Kemarin hal itu terjadi 20.734 kali.
Angka yang penting adalah yang kecil
Memuat semuanya dari awal, dengan cache opcode dimatikan, memakan waktu sekitar 132 milidetik. Angka itulah yang akan menjadikan ini masalah, dan itu bukan angka yang dibayar server.
Jika opcode sudah dikompilasi dan disimpan di memori bersama, yang tersisa hanyalah pembacaan isi direktori dan satu stat() per berkas, karena validasi stempel waktu aktif: 0,33 milidetik. Dengan lalu lintas kemarin, itu kurang dari tujuh detik kerja sepanjang hari.
Di antara keduanya ada pengukuran ketiga, 18,2 milidetik, yang diambil dengan cache opcode membaca dari disk, bukan dari memori. Ini batas atas, bukan angka yang sebenarnya — inilah yang terjadi bila cache ada tetapi lebih lambat daripada cache yang sesungguhnya. Angka ini dilaporkan karena hanya inilah angka hangat yang dapat diukur dari baris perintah, dan berpura-pura sebaliknya adalah kesalahan yang mudah terjadi.
Jadi: ini hampir tidak memakan biaya, dan hampir tidak memakan biaya sepenuhnya berkat hal lain. Matikan cache opcode, dan baris yang sama menjadi empat ratus kali lebih mahal. Itu ketergantungan yang nyata, dan sebaiknya diketahui sejak awal daripada ditemukan saat pemutakhiran.
Apa sebenarnya isi 1,5 megabyte itu
Empat puluh tujuh persen di antaranya — 715 kilobyte dalam 26 berkas — adalah keluarga desain penghitung. Untuk menggambar sebuah gambar penghitung, hanya diperlukan tepat satu di antaranya. Ke-25 lainnya dimuat, dideklarasikan, dan tidak pernah disentuh.
Setelah itu: 189 kilobyte data bendera, yang dibutuhkan di halaman geografi; 158 kilobyte pustaka diagram, yang dibutuhkan saat ada yang menggambar diagram. Keduanya tidak terlibat dalam menyajikan gambar penghitung, padahal itulah permintaan yang paling sering dijawab layanan ini.
Biaya yang terlihat dari hal itu adalah memori, bukan waktu. Puncak memori per permintaan naik sekitar empat megabyte, dan berbeda dengan opcode — yang dipakai bersama oleh semua proses — bagian itu dibayar per permintaan, secara paralel, oleh setiap worker sekaligus.
Sudah ada yang menyadarinya
Pola glob-nya adalah lib/*.php. Pola ini tidak rekursif, dan ada dua direktori tepat di bawahnya: lib/live/ berukuran 229 kilobyte dan lib/recht/ berukuran 182 kilobyte. Empat ratus kilobyte yang dulu ada di jalur pemuatan dan sekarang tidak lagi.
Keduanya dipindahkan karena besar dan jarang dibutuhkan: bagian-bagian statistik dan teks hukum. Berada satu direktori lebih dalam, itulah seluruh mekanismenya. Tidak ada konfigurasi, tidak ada lazy loader, tidak ada peta autoload — sebuah berkas entah tercakup oleh glob, entah tidak.
Itu perbaikan yang nyata dan patut disebutkan, karena langkah berikutnya yang tampak jelas adalah autoloader, dan autoloader di sini akan menjadi perubahan besar untuk memecahkan masalah yang oleh sebuah mkdir sudah dipecahkan dua kali.
Mengapa ini dipertahankan
Satu glob adalah hal paling sederhana yang mungkin berhasil, dan buktinya memang berhasil: sepertiga milidetik, di server kecil, pada jalur yang harus cepat. Menggantinya dengan require per berkas berarti setiap berkas baru membutuhkan satu baris di suatu tempat, dan baris yang terlupakan akan menghasilkan kesalahan fatal di produksi, bukan sekadar beban yang sedikit lebih besar.
Yang memang dibutuhkan adalah hal yang sejak awal membuatnya bisa bertahan, dalam bentuk tertulis: jika sebuah berkas di lib/ menjadi besar, berkas itu dipindahkan ke subdirektori dan di-require di tempat ia digunakan. Itulah aturan yang selama ini diikuti kedua direktori tersebut, dan sampai sekarang aturan itu tidak tertulis di mana pun.
Versi umumnya lebih membosankan daripada pengukurannya. “Semuanya memuat semuanya” biasanya bentuk yang salah, dan ada baiknya mengukur berapa biayanya sebelum membangunnya ulang. Di sini biayanya 0,33 milidetik dan empat megabyte, dan empat megabyte itulah yang patut diawasi, karena jumlahnya bertambah seiring banyaknya permintaan serentak, sedangkan milidetiknya tidak.