11 puan yazan GN⁺ 2026-03-21 | 2 yorum | WhatsApp'ta paylaş
  • Rust ile yazılmış WASM ayrıştırıcısı yapısal olarak hızlı olsa da, JS-WASM sınırındaki veri kopyalama ve serileştirme ek yükü performans darboğazı olarak ortaya çıktı
  • serde-wasm-bindgen üzerinden doğrudan nesne döndürme, JSON serileştirmesinden %9–29 daha yavaştı; bunun nedeni çalışma zamanları arasındaki ayrıntılı dönüştürme maliyetiydi
  • Tüm hattı TypeScript'e taşımak, aynı mimaride tek çağrı performansında 2.2–4.6 kat hızlanma sağladı
  • Akış işleme tarafında cümle düzeyinde önbellekleme ile O(N²)→O(N) iyileştirmesi sayesinde toplam işlem hızında 2.6–3.3 kat artış elde edildi
  • Sonuç olarak, WASM'in hesaplama yoğun ve düşük sıklıkta çağrılan işler için uygun, JS nesnesi ayrıştırma veya sık çağrılan fonksiyonlar için ise uygun olmadığı doğrulandı

Rust WASM ayrıştırıcısının yapısı ve sınırları

  • openui-lang ayrıştırıcısı, LLM'in ürettiği DSL'yi React bileşen ağacına dönüştüren 6 aşamalı bir hat olarak yapılandırılmıştır
    • Aşamalar: autocloser → lexer → splitter → parser → resolver → mapper → ParseResult
    • Her aşama belirteçleştirme, sözdizimi analizi, değişken çözümleme, AST dönüşümü gibi işleri yapar
  • Rust kodunun kendisi hızlı olsa da, JS↔WASM arasında dize kopyalama, JSON serileştirme ve ters serileştirme her çağrıda gerçekleşir
    • Girdi dizesi kopyalama (JS→WASM), Rust içinde ayrıştırma, sonuç JSON'unu serileştirme, JSON'u kopyalama (WASM→JS), JS tarafında ters serileştirme
  • Bu sınır ek yükü toplam performansa hakim oldu; darboğaz Rust'ın hesaplama hızı değildi

serde-wasm-bindgen denemesi ve başarısızlığı

  • JSON serileştirmesinden kaçınmak için, Rust struct'larını doğrudan JS nesnesi olarak döndüren serde-wasm-bindgen uygulandı
  • Ancak %30 yavaşlama gözlendi
    • JS, Rust struct bellek düzenini doğrudan okuyamaz ve çalışma zamanları arasındaki bellek yerleşimi farklı olduğundan alan bazında dönüştürme gerekir
    • Buna karşılık JSON serileştirme, Rust içinde tek seferde bir dize üretir; JS tarafında ise optimize edilmiş JSON.parse ile işlenir
  • Karşılaştırma sonuçları
    Fixture JSON round-trip serde-wasm-bindgen Değişim
    simple-table 20.5µs 22.5µs -9%
    contact-form 61.4µs 79.4µs -29%
    dashboard 57.9µs 74.0µs -28%

TypeScript'e geçiş ve performans artışı

  • Aynı 6 aşamalı yapı tamamen TypeScript'e taşındı, WASM sınırı kaldırıldı ve doğrudan V8 heap'i içinde çalıştırıldı
  • Tek çağrı bazlı benchmark sonuçları
    Fixture TypeScript WASM Hız artışı
    simple-table 9.3µs 20.5µs 2.2 kat
    contact-form 13.4µs 61.4µs 4.6 kat
    dashboard 19.4µs 57.9µs 3.0 kat
  • Yalnızca WASM'i kaldırmak bile çağrı başı maliyeti ciddi ölçüde düşürdü, ancak akış yapısındaki verimsizlik hâlâ sürüyordu

Akış ayrıştırmada O(N²) sorunu ve iyileştirme

  • LLM çıktısı birden fazla parça hâlinde geldiğinde, her seferinde biriken tüm dizenin yeniden ayrıştırılması nedeniyle O(N²) verimsizliği oluşuyordu
    • Örnek: 1000 karakterlik bir belgeyi 20 karakterlik parçalarla 50 kez ayrıştırmak → toplam 25.000 karakter işleme
  • Çözüm olarak cümle düzeyinde artımlı önbellekleme (incremental caching) getirildi
    • Tamamlanmış cümleler önbelleğe alınır, yalnızca devam eden cümle yeniden ayrıştırılır
    • Önbellekteki AST ile yeni AST birleştirilerek sonuç döndürülür
  • Tüm akış için benchmark
    Fixture Naif TS Artımlı TS Hız artışı
    simple-table 69µs 77µs Yok
    contact-form 316µs 122µs 2.6 kat
    dashboard 840µs 255µs 3.3 kat
  • Cümle sayısı arttıkça önbellek etkisi büyüdü ve toplam işlem hacmi doğrusal olarak iyileşti

WASM kullanımına dair çıkarımlar

  • Uygun olduğu durumlar
    • Hesaplama yoğun ve etkileşimi az işler: görüntü/video işleme, şifreleme, fizik simülasyonu, ses kodekleri vb.
    • Mevcut yerel kütüphanelerin taşınması: SQLite, OpenCV, libpng vb.
  • Uygun olmadığı durumlar
    • JS nesnelerine dönüştürülen yapılandırılmış metin ayrıştırma: serileştirme maliyeti baskın hâle gelir
    • Kısa girdilerle sık çağrılan fonksiyonlar: sınır maliyeti hesaplamadan büyüktür
  • Temel dersler
    1. Dil seçmeden önce darboğazın nerede olduğunu profillemek gerekir
    2. serde-wasm-bindgen ile doğrudan nesne aktarımı daha maliyetlidir
    3. Algoritmik karmaşıklığı iyileştirmek, dil değiştirmekten daha etkili olabilir
    4. WASM ve JS heap paylaşmaz; dönüştürme maliyeti her zaman vardır

Nihai sonuç: TypeScript'e geçiş ve artımlı önbellekleme ile çağrı başına 2.2–4.6 kat, tüm akışta 2.6–3.3 kat performans artışı elde edildi

2 yorum

 
bbulbum 2026-03-23

Amaç, ileri düzey Rust performans iyileştirme yazılarını hafifçe iğnelemek değil miydi..

 
GN⁺ 2026-03-21
Hacker News yorumları
  • Asıl mesele Rust yerine TypeScript değil, O(N²)'den O(N)'e indirilen akış algoritması düzeltmesi
    Yalnızca ifade düzeyinde önbellekleme yapan bu değişiklik bile tek başına 3,3 kat iyileşme sağlamış
    Dil seçimi ayrı bir konu; kullanıcı açısından hissedilen gecikme (latency) iyileşmesinin başlıca nedeni bu kısım
    Başlık sanki bu ilginç mühendislik noktasını olduğundan küçük göstermiş

    • uv projesinde de durum aynı. İnsanlar sadece “rust rulez!” diye bağırıyor ama gerçek kazanım dilden değil, algoritma iyileştirmesinden geliyor
    • Tıklama tuzağını aşıp özünü işaret ettiğin için teşekkürler
      Yazının kendisi ilgi çekici ama bugünlerde aşırı tıklama odaklı başlıklardan bıkmış durumdayım
    • n² ifadesi biraz abartılı görünüyor
      Yöntem, her çağrının süresini ölçüp medyanı (median) kullanmak; ama tarayıcı ortamında zamanlama saldırılarına karşı savunma mantığı olan JS motorlarında bunun doğruluğu soru işareti
    • Sonuçta bunun yanıltıcı bir başlığa daha yakın olduğunu düşünüyorum
  • “Kodu L dilinden M diline yeniden yazdım ve hızlandı” demek zaten beklenen bir sonuç
    Çünkü bu, dolaşmış ve hatalı kararları düzeltme ve sonradan ortaya çıkan daha iyi yaklaşımları uygulama fırsatı veriyor
    Aslında L=M olsa bile aynı şey geçerli; hız artışı dilden değil, yeniden yazma ve yeniden tasarlama sürecinden geliyor

    • Şimdi üçüncü bir kişi, orijinali bilmeden TypeScript sürümünü tekrar Rust ile baştan yazsa performans yine artabilir
    • Aynı dilde tekrar yazınca bile sık sık iyileşme etkisi görüyorum
  • Rust ve JS sınırında nesne serileştirme performansını iyileştirmeye çalışırken daha derine indim
    serde'nin yaklaşımı performans açısından pek iyi görünmüyordu; bunu iyileştirme denememi blog yazımda anlattım

  • Open UI'ın neden WASM ile ilgili işler yapmadığını merak etmiştim
    Ama bu yeni şirketin de Open UI adını kullanması kafa karıştırdı
    Asıl Open UI W3C Community Group, 5 yılı aşkın süredir HTML için popover, özelleştirilebilir select, invoker command, accordion gibi standartlar üreten bir grup
    Gerçekten harika işler yapıyorlar

  • “JSON gidiş dönüşünü atlayalım” denilerek serde-wasm-bindgen entegre edilmiş ama sonuçta bu bana ikili biçimde JSON'un yeniden icadı gibi görünüyor
    Günümüzde V8'in JSON'u zaten çok iyi optimize edilmiş durumda ve simdjson gibi uygulamalar saniyede gigabaytlar düzeyinde işleyebiliyor
    JSON'un darboğaz olma ihtimali düşük görünüyor

  • O blogun tasarımını gerçekten çok beğendim
    Kaydırma konumuna göre başlıkları vurgulayan “scrollspy” kenar çubuğu özellikle çok iyiydi
    Claude'un söylediğine göre sanırım fumadocs.dev ile yapılmış

    • İlginç. Ben de yakında iyi bir dokümantasyon sitesi yapmam gerekeceğini düşünüyorum
  • Rust WASM ayrıştırıcısının amacını pek anlayamadım
    Yazıda bu kısım net olmadığı için daha fazla açıklama gerekiyor

    • LLM'in ürettiği UI bileşenlerini tanımlayan özel bir dil kullandıkları söyleniyor
      Bu da muhtemelen prompt injection kaynaklı bilgi sızıntısını önlemek için
      Ayrıştırıcı, LLM'den akış halinde gelen parçaları derleyip gerçek zamanlı UI oluşturuyor
      Önceden her parçada ayrıştırıcı en baştan yeniden başlatılıyordu; bunu artımlı işleme yaklaşımına çevirince (Rust→TypeScript taşıması sırasında) performans büyük ölçüde artmış
  • TypeScript'in bugünlerde Golang tabanlı çalıştığına dair bir merakım vardı

    • TypeScript derleyicisini Go ile yeniden yazma projesi var; sanırım kastedilen o
  • Şaka bir yana, tekrar Rust ile yeniden yazılırsa belki bir 3 kat daha performans artışı gelir /s