Kıyaslamalar
Phasis, dağıtım ağırlıklı JavaScript iş yüklerinde V8'den yaklaşık iki büyüklük mertebesi daha yavaştır. Bu üst sınır, PHP üzerinde çalışan bir yorumlayıcının yerel bir JIT derleyicisine kıyasla doğasında olan maliyetidir. Sistemi gömenler için soru "V8 ile nasıl karşılaştırılıyor?" değil, "yaptığım iş için yeterince hızlı mı?" sorusudur. Çoğu gömme iş yükü için yanıt evettir.
Üst sınırın önemli olmadığı durumlar
- Şablon oluşturma — tipik bir sayfanın SSR tarzı görüntülenmesi 10 ms'den çok daha kısa sürer.
- Doğrulama kuralları — form doğrulaması için kullanıcı tarafından sağlanan JS mikrosaniyeler içinde tamamlanır.
- Veri dönüştürme — yüzlerce öğe üzerinde
array.map(transform)işlemi onlarca milisaniyede tamamlanır. - Korumalı alan çalıştırıcıları — ana makinede 1 saniyelik sınırı olan kısa kullanıcı betikleri için fazlasıyla zaman kalır.
Üst sınırın önemli olduğu durumlar
- Hesaplama ağırlıklı iç döngüler — görüntü işleme, büyük dizilerde indirgeme, simülasyonlar. Hesaplamayı yerel bir PHP kitaplığına taşıyıp bunu bir ana makine işlevi olarak sunun.
- Gerçek zamanlı animasyon — 60 fps sağlayan her şey. Bu JS istemci tarafında (tarayıcı veya yerel uygulama) olmalıdır; gömülü altyapıda değil.
- Hesaplama açısından pahalı algoritmaların JS ile yeniden uygulanması — kriptografi, sıkıştırma, ayrıştırma. PHP'te yerel karşılıklar 1000× daha hızlıdır; bunları kullanın.
Doğru düşünce modeli: Phasis, PHP biçimli uygulamalara gömülü JS biçimli mantık için bir tutkal katmanıdır. Hesaplamayı PHP ana makine yapar; yapılandırma, dallanma ve küçük dönüşümleri JS katman yürütür.
Altyapıyı hızlı yapan etkenler (naif bir ağaç gezginine kıyasla)
- Bayt kodu VM — sık çalışan dağıtım işlemlerinin çoğu AST üzerinden değil,
VM::executeopcode anahtarlaması üzerinden yürür. - Özel çağrı yığını — her JS çağrısı durumu
VM::executeiçinde tutar ve çağıranın çerçevesini bir havuza kaydeder; her JS çağrısı için yeni bir PHP çerçevesi oluşturulmaz. Bkz. Bayt Kodu VM § Özel çağrı yığını. - Satır içi önbellekler — PC başına tek biçimli önbellek, prototip zincirini gezmeden prototip yöntemi ve örneği okumayı (
c.method()örüntüsü) sağlar. - Çerçeve anlık görüntülü üreticiler — basit üretici gövdeleri, PHP Fiber'ını geçmek yerine dağıtım durumunu bir yığın nesnesine yakalayarak askıya alınır.
- JsToPhp dönüştürücüsü — sayısal veya yerel değişken ağırlıklı gövdeler (
obj.method(),new Ctor()vethis.memberokumaları dahil), PHP closure'larına derlenir; PHP 8.5'in izleme JIT'i bunları yerel makine koduna indirger. - JSON.stringify önbelleği —
JSON.stringify(o), aktarılabilir sürüm geçersizleştirme mekanizmasıyla çıktısını girdi nesnesinde önbelleğe alarak derin klonlama deyimini hızlandırır:JSON.parse(JSON.stringify(o)).
Kendi iş yükünüzü ölçme
php bench/run.php
Bu, bench/microbench.js altında sunulan mikro kıyaslama paketini çalıştırır — birkaç sentetik iş yükünü (döngü aritmetiği, özyinelemeli işlevler, nesne oluşturma, prototip yöntemi çağrıları, diziye push, JSON gidiş-dönüşü vb.) yürütür ve her test için medyan geçen süreyi yazdırır. Makul olup olmadığını kontrol etmek için kullanışlıdır; güncel sayılar her CI kıyaslama çalıştırmasında BENCH.md konumuna kaydedilir.
Kendi kodunuz için herhangi bir betiği ekleyin:
php -d xdebug.mode=off bench/run.php path/to/your-script.js
PHP düzeyinde profil çıkarırken Xdebug profil aracı, tıpkı diğer tüm PHP uygulamalarında olduğu gibi Phasis üzerinde çalışır. Bir betiği xdebug.mode=profile altında çalıştırın ve hangi Phasis\ sınıflarının baskın olduğunu görmek için cachegrind çıktısını inceleyin.
Yol haritası
Erişilebilirlik açısından kabaca sıralandığında, V8 farkını daha fazla kapatabilecekler:
- Polimorfik satır içi önbellekler — tek bir
LOAD_MEMBERçağrı noktası, yavaş dağıtıma geçmeden önce 2-4 önbelleğe alınmış şekli tutabilir. Farklı alıcı türlerini işleyen kodlara yardımcı olur. yield*ve çerçeve anlık görüntüsü oluşturucu yolunda try-with-yield — bu şekiller şu anda Fiber destekli ağaç yürüyücüsüne yönlendirilir. Anlık görüntüye uygun olmaları için her birinin açık durum makinesi işleme mantığına (delege yineleyici iletimi, askıya alma boyunca korunan işleyici yığını) ihtiyacı vardır.- Anlık görüntülerde asenkron oluşturucular ve
await— belirtim, oluşturucu askıya almayı mikro görev kuyruğuyla birleştirir. Bayt kodu gövdesi hemyieldhem deawaitdesteği kazandığında asenkron oluşturucular da anlık görüntülere uygun hâle gelir. - JsToPhp'de parametre türü çıkarımı — işlev parametreleri varsayılan olarak sayısal türdedir, bu yüzden
function (obj) { obj.method() }derleyiciyi durdurur. Parametrelerin gövdede nasıl kullanıldığından nesne türünü çıkarmak, alıcınınnewaracılığıyla yerel olarak oluşturulmasını gerektirmeden işlev bağımsız değişkenleri üzerinde yöntem çağrılarını mümkün kılar. - Doğrudan opcache çıktısı üretimi — opcache biçimli işlem kodlarını doğrudan yazarak JsToPhp'nin
eval()adımını atlayın. En kapsamlı iş budur; diğerleri mevcut mimari içinde yapılabilir.
Bunların hiçbiri Phasis hedeflediği yerleştirme iş yükleri için gerekli değildir.