Ölçüm · 21–23 Ağustos 2026 · English

On Dil,
Tek API


Aynı API. On dil. Üç ölçek. Otuz uygulama. Hepsi bütün testleri geçti. Sonra tokenleri saydık. Sonra hızı, CPU'yu ve RAM'i ölçtük.

İki önemli sonuç. Uygulama büyüdükçe token farkı daralıyor. Ve token sıralaması, hız sıralamasının neredeyse tam tersi.

30uygulama
259test, hepsi geçti
2.80×token farkı
40×hız farkı
57×bellek farkı

Üç ölçek

Küçük = sade CRUD, 7 rota. Orta = kimlik doğrulama, roller, satır bazlı erişim, ara katman, yapılandırılmış günlük, hata kodları, sayfalama, sıralama, durum makinesi ve kademeli silme eklenir. 16 rota. Büyük = modül ayrımı, ETag eşzamanlılığı, idempotanlık anahtarları, mantıksal silme, denetim kaydı, giden kutusu, kota, toplu yazma, arama, raporlar, metrikler, yorumlar ve kullanıcı yönetimi eklenir. 34 rota.

İlk önce şartname yazıldı. Sonra testler. Kod en son yazıldı. Gerçek bir sunucu çalışıp gerçek HTTP üzerinden bütün testleri geçmeden hiçbir ölçüm sayılmadı. Orta ve büyük ölçek ayrıca günlük denetimini de geçmek zorunda: bu denetim sunucunun stdout çıktısını okur ve her günlük satırını doğrular.

Uygulama büyüdükçe token farkı daralıyor

Çubuk = o ölçekteki en ucuz dile göre maliyet. Her dil için üç çubuk: küçük, orta, büyük. Pahalı diller uygulama büyüdükçe belirgin biçimde ucuzluyor.

Python S1.00× M1.00× L1.00×
TypeScript S1.28× M1.13× L1.12×
C# S1.12× M1.08× L1.15×
Java S1.51× M1.35× L1.38×
PHP S1.94× M1.45× L1.48×
Go S1.75× M1.75× L1.56×
Rust S1.66× M1.72× L1.66×
Zig S2.08× M1.87× L1.84×
C++ S4.24× M2.50× L2.01×
C S5.05× M3.43× L2.80×
küçük, 7 rota orta, 16 rota büyük, 34 rota
Alt seviye dillerin cezası sabit bir maliyet, çarpan değil.

C, C++ ve Zig; HTTP ayrıştırıcısını, JSON ayrıştırıcısını, JSON yazıcısını ve soket döngüsünü bir kez yazar. Python ve C# bunların tamamını hazır alır. Yani Python çok önde başlar, sonra ek bir kazanç elde etmez. 35. rotanın maliyeti her dilde aynıdır.

En kötü ile en iyi arasındaki fark: 7 rotada 5.05× → 16 rotada 3.43× → 34 rotada 2.80×.

Sonuç: oyuncak bir uygulamada ölçüm yaparsanız C'yi fazla cezalandırırsınız — neredeyse iki kat.

Token maliyeti

Sıralamak için herhangi bir başlığa tıklayın.

Dilküçükorta büyükbüyük token büyük satır
Python1.00× 1.00×1.00× 10,5581,321
TypeScript1.28× 1.13×1.12× 11,8741,493
C#1.12× 1.08×1.15× 12,1801,360
Java1.51× 1.35×1.38× 14,5211,601
PHP1.94× 1.45×1.48× 15,6071,771
Go1.75× 1.75×1.56× 16,5182,338
Rust1.66× 1.72×1.66× 17,5602,147
Zig2.08× 1.87×1.84× 19,4181,995
C++4.24× 2.50×2.01× 21,2542,467
C5.05× 3.43×2.80× 29,5323,245

Hız, CPU, bellek

Büyük uygulama. 10,000 istek, teker teker. p50 = ortadaki istek. p99 değil p50 kullanın: Windows zamanlayıcı adımı p99'u yanıltıyor. Soğuk başlangıçtan ölçüm aracının kendi tabanı çıkarıldı.

Sıralamak için herhangi bir başlığa tıklayın. Sıralamayı p50 üzerinden yapın: milisaniyenin altındaki uygulamalar için req/s gürültülüdür. Ayrıntı: METHODOLOGY.md.

Dilp50 msreq/s CPU ms/istekboşta RAM soğuk başlangıç
C++0.218 2,543 0.070 5.2 MB 58 ms
C0.240 2,084 0.059 4.2 MB 47 ms
Zig0.254 1,986 0.069 3.3 MB 57 ms
Go0.311 1,888 0.230 8.6 MB 55 ms
Rust0.327 1,412 0.150 6.2 MB 69 ms
TypeScript0.441 1,198 0.356 67.0 MB 452 ms
C#0.444 850 0.653 50.9 MB 712 ms
Java0.595 760 1.613 191.0 MB 5,275 ms
Python1.621 266 1.764 50.0 MB 1,012 ms
PHP8.636 62 5.097 34.5 MB 166 ms

Token sıralaması, hız sıralamasının tersi

Ucuz token, yavaş kod. Pahalı token, hızlı kod.

C ve C++ en çok tokeni harcıyor — ve hızda birinci ile ikinci oluyor. Python en az tokeni harcıyor — ve hızda 10 dil içinde 9. sırada. İki liste neredeyse birbirinin aynası.

Yani burada tek bir “en iyi dil” yok. Sadece bilerek seçtiğiniz bir denge var. Hiçbir dil iki uçta da iyi değil.

Sıralamak için herhangi bir başlığa tıklayın.

Diltoken sırasıhız sırası kaymaKısa yorum
C++91 +8en hızlı, token'da sondan ikinci
C102 +8en az CPU, en hızlı başlangıç, en çok token
Zig83 +5en az RAM, 3.3 MB
Go64 +2her alanda dengeli, çok satır
Rust75 +2hızlı, güvenli, çok token
TypeScript26 −4en dengeli, 67 MB yer kaplıyor
C#37 −4yoğun kod, orta hız
Java48 −4JIT sonradan hızlandırıyor, 5 s başlangıç, 191 MB
PHP510 −5sıfır bağımlılık, ama dosya deposu yavaşlatıyor
Python19 −8en az token, yavaş

Kayma = token sırası eksi hız sırası. Artı değer, dilin token maliyetinin ima ettiğinden daha hızlı olduğu anlamına gelir.

Önce kendi hatalarımızı düzelttik

İki dil kendi yüzünden değil, bizim yüzümüzden kötü görünüyordu.

PHP'de OPcache kapalıydı. php -S CLI SAPI ile çalışır ve orada opcache.enable_cli varsayılan olarak kapalıdır. Bu yüzden PHP her istekte uygulamanın tamamını kaynaktan yeniden derliyordu. Hiçbir gerçek kurulum böyle çalışmaz. Bunu düzeltmek orta ölçekte PHP'nin p50 değerini neredeyse yarıya indirdi.

C ve C++ keep-alive kullanmıyordu. İkisi de her yanıtta Connection: close gönderiyordu, yani her istek için yeni bir TCP el sıkışması. HTTP/1.1 varsayılanı kalıcı bağlantıdır. Zig de çıplak soketle, çerçeve olmadan yazıldı ve bunu doğru yapıyor; hatanın bize ait olduğunu bu kanıtladı. Düzeltmeden sonra C küçük ölçekte 96 → 3,454 req/s, p50 11.59 → 0.166 ms. Düzeltmeden önce C'yi hızda 8. sıraya koymuştuk. C aslında zirveye yakın.

Doğru keep-alive, C ve C++'a yaklaşık %26 daha fazla token'a mal oldu. Gerçek bir denge: protokole uygun kod daha fazla koddur. Buradaki bütün sayılar düzeltilmiş hâlleridir.

PHP'nin süresi gerçekte nereye gidiyor

OPcache düzeltmesinden sonra katman katman ölçtük: aynı sunucu, temiz depo, sadece GET. Sonuç bizi şaşırttı.

Katmanp50bu katmanın eklediği
çıplak PHP, çerçeve yok0.874 ms —
+ Slim kurulumu, depo yok, iş mantığı yok5.113 ms +4.24 ms
+ küçük ölçek depomuz ve rotalar5.384 ms +0.27 ms
+ büyük ölçek depomuz ve rotalar6.410 ms +1.30 ms

Çıplak PHP 0.874 ms — C# ve Python'u geçiyor. Farkın yaklaşık %94'ü, Slim'in konteyneri, yönlendiricisi ve ara katman yığınının her istekte sıfırdan kurulmasından geliyor. Bu, PHP'nin gerektirdiği paylaşımsız modeldir. Yavaş olan PHP dili değil. Yavaş olan bizim depomuz da değil. Diğer bütün diller yönlendiricisini başlangıçta bir kez kurar ve süreç boyunca saklar.

Bu yüzden çerçeveyi tamamen çıkardık. PHP artık hiçbir çerçeve olmadan ölçülüyor.

Go veya Rust'ta çerçeve tabandır; daha azıyla HTTP sunamazsınız. PHP'de çerçeve bir tercihtir. PHP tasarımı gereği bir istek işleyicisidir; $_SERVER['REQUEST_URI'] üzerinde çalışan tek bir ön denetleyici sıradan PHP'dir ve üretimde kullanılır. Sadece Slim'i ölçmek, PHP'yi birçok PHP geliştiricisinin hiç vermediği bir karar için cezalandırır.

Yani buradaki PHP sıfır bağımlılıklıdır: composer yok, vendor yok, otomatik yükleyici yok. Sadece public/index.php ve kendi dosyaları. Aynı depo, aynı isimler, aynı iş mantığı. Aynı 22 / 98 / 139 testi geçiyor.

Çerçeveli sürümü çıkarmadan önce iki yolu da ölçtük. Bu yüzden çerçevenin maliyeti bir tahmin değil, ölçülmüş bir sayıdır:

10,000 istekçerçeve yokSlim ile kazanç
küçük ölçek p501.362 ms 6.102 ms4.5×
orta ölçek p501.452 ms 6.306 ms4.3×
büyük ölçek p508.636 ms 17.588 ms2.0×
büyük CPU ms/istek5.097 9.3551.8×
büyük token15,607 16,2381.04×

Çerçeve olmadan küçük ölçekte 4.5×, orta ölçekte 4.3×, büyük ölçekte 2.0× daha hızlı, 5× daha az CPU — ve token maliyeti de daha düşük. Üstüne composer dosyası olmadığı için sıfır manifest. Yani çerçeve her istekte yaklaşık 4.2 ms'e mal oldu ve ölçtüğümüz hiçbir şeyi iyileştirmedi. Eski Slim ölçümleri perf-variance/removed-slim-run*.json içinde saklanıyor, isteyen kontrol edebilir.

Buradaki PHP sayıları üç koşunun ortancasıdır. Aslında buna pek gerek yoktu: üç koşu küçük ölçekte 1.362, 1.361, 1.376 ms verdi — %1.1 aralığında. PHP, bütün kıyaslamada en tekrarlanabilir uygulamalardan biri. Eski çerçeveli sürüm ise 13.73, 6.07, 6.10 ms arasında salınıyordu, çünkü otomatik yükleyicisi her istekte yaklaşık yüz dosyaya dokunuyordu. Yani oynaklık çerçeveden geliyordu, dilden değil.

Üçüncü PHP düzeltmesi: depomuz O(n) idi

Çerçeve olmadan bile PHP büyük ölçekte kötü görünüyordu. Nedenini ölçtük ve suç yine bizdeydi.

Depo işlemiküçük depo 501 B büyük depo 144 KB
file_get_contents0.049 ms0.039 ms
file_put_contents0.327 ms0.741 ms
json_decode0.016 ms8.581 ms
tam okuma + çözme + kodlama + yazma0.641 ms11.519 ms

Sorun hiçbir zaman dosya G/Ç değildi. JSON'du. Büyük ölçek bir denetim kaydı ve giden kutusu biriktiriyor; bizim depomuz ise her istekte tüm veri kümesini yeniden serileştiriyordu. Yani PHP, diğer bütün dillerin RAM'deki bir listeye O(1) ekleme olarak yaptığı iş için istek başına O(toplam durum) ödüyordu. Bu bizim tasarımımız, PHP değil.

Düzeltme: denetim kaydı ve giden kutusu, yalnızca ekleme yapılan JSON Lines dosyalarına taşındı; /stats ve /metrics O(1) kalsın diye store.json içine sayaçlar eklendi; boşaltma O(1) kalsın ve delivered yeniden yazılmak yerine türetilsin diye bir su seviyesi işareti eklendi.

Tek bir görevde 2,000 durum değişikliğip50 başlangıç p50 bitişsapma
düzeltmeden önce7.783 ms18.402 ms2.36×
düzeltmeden sonra7.523 ms7.547 ms1.00×

Düz. Büyük ölçekte p50 25.2 → 8.6 ms'ye düştü. Düzeltmenin maliyeti: +1,216 token, çünkü O(1) kalıcılık O(n)'den daha fazla koddur. Bu, PHP'yi büyük ölçek token sıralamasında 4.'lükten 5.'liğe taşıdı. Dürüst bir denge ve buradaki sayılar bunu içeriyor.

PHP'de üç engel bulundu. Üçü de bizimdi.

OPcache kapalı. Çerçeve her istekte yeniden kuruluyor. Depo O(n). Üçünden ikisi, katman katman ölçene kadar görünmezdi. Ders: PHP'nin paylaşımsız modeli, durumun bellekte yaşadığını varsayan her kıyaslamayla çatışır ve saf bir aktarım bu bedeli sessizce PHP'ye yazar. Her PHP kıyaslamasını — bunu da — bunu bilerek okuyun.

Öne çıkan sonuçlar

Yük altında bozulan tek dil hâlâ PHP

Depo düzeltmesinden sonra büyük ölçekte PHP, 100 istekte 2.36 ms'den 10,000 istekte 8.64 ms'ye çıkıyor. Kalan artış, depoda canlı alan verisi olarak duran 1,000 mantıksal silinmiş görev satırından geliyor — bu satırları o ölçekteki her dil de tutuyor. Meşru bir maliyet, bu yüzden kalıyor.

Çerçeve, PHP'ye istek başına yaklaşık 4.2 ms'e mal oldu ve hiçbir şey kazandırmadı

Çerçeve olmadan hem daha hızlı hem daha küçük: küçük ölçekte 4.5×, orta ölçekte 4.3×, büyük ölçekte 2.0× daha hızlı p50, 5× daha az CPU ve 16,238 yerine 15,607 token. Çerçeve ayrıca bir composer.json ve bir vendor/ ağacı ekliyor. Ölçtüğümüz hiçbir şey bununla iyileşmedi, bu yüzden PHP çerçevesiz ölçülüyor.

Java JIT 2.2× değerinde

Java çalışırken hızlanıyor: p50 1.304 → 0.595 ms. Belirgin biçimde iyileşen tek dil, sapma 0.46×. Ama bedeli 5,275 ms soğuk başlangıç ve 191 MB RAM. Uzun süre açık kalan sunucu için uygun. Sıfıra ölçeklenen kurulum için kötü.

En az CPU'yu C kullanıyor

Büyük uygulamada istek başına 0.059 CPU ms. Bu, PHP'den 86×, Java'dan 27× daha az. Üstelik en hızlı soğuk başlangıç: 47 ms.

En az RAM'i Zig kullanıyor

Boşta 3.3 MB. Java 191 MB kullanıyor — 57× fazlası. Zig bunu sadece standart kütüphaneyle, sıfır bağımlılıkla ve üç ölçeğin hepsinde yapıyor.

C# yoğun, şişkin değil

C#, küçük ve orta ölçekte satır sayısında Python'u geçiyor — 138'e 134 ve 472'ye 451. Modern C#, eski kurumsal kalıp kod değil.

Çalışma zamanı farkı, token farkını eziyor

Token farkı 2.80×. Soğuk başlangıç 112×. CPU 86×. RAM 57×. Hız 40×. Kaynak kod boyutu, burada ölçülen en düz eksen.

Bir sayıyı alıntılamadan önce bunları bilin