- V8 motorunda JSON.stringify fonksiyonunun performansı 2 katından fazla artırılarak veri serileştirme hızında iyileşme sağlandı
- Yan etkisiz nesneler için bir optimizasyon yolu eklenerek çok sayıdaki savunmacı kontrol mantığı atlandı ve yaygın veri nesnelerinde büyük hız artışı elde edildi
- String işleme sırasında 1 bayt/2 bayt ayrımı, SIMD kullanımı, geçici tampon yapısının değiştirilmesi gibi donanım ve bellek tarafında gelişmiş yöntemler uygulandı
- Sayı dönüştürme sürecinde mevcut Grisu3 algoritması Dragonbox ile değiştirildi; böylece
Number.toString() çağrılarının genelinde daha hızlı dönüşüm mümkün hale geldi
- Bazı argüman ve biçimlerde normal serileştirme yoluna geri dönülse de, çoğu web geliştirme senaryosunda optimizasyon etkisinden otomatik olarak yararlanılabiliyor
Genel bakış
JSON.stringify, JavaScript'te veriyi stringe dönüştüren temel bir fonksiyondur
- Bu fonksiyondaki performans artışı, ağ istekleri veya localStorage'a kayıt gibi web için çok önemli işlemleri de olumlu etkiler
- En güncel V8 mühendisliğiyle bu özelliğin hızı 2 katından fazla artırıldı ve başlıca optimizasyon yöntemleri ayrıntılı biçimde tanıtıldı
Yan etkisiz Fast Path yolu
- Optimizasyonun çekirdeği, yalnızca yan etki (side-effect) olmayan durumlarda kullanılabilen hızlı serileştirme yolunun uygulanmasıdır
- Bu durumlarda nesneler özyinelemeli değil, iteratif bir yapıyla dolaşıldığı için stack overflow kontrolüne gerek kalmaz ve daha derin nesnelerin serileştirilmesi de mümkün olur
- Veri nesnesi basit olduğunda V8, yavaş genel mantık yerine bu Fast Path'i kullanarak birçok kontrolü atlar ve hızı artırır
Farklı string gösterimlerinin işlenmesi
- V8, 1 bayt/2 bayt karakterlere (ASCII/ASCII dışı) göre stringleri farklı biçimde saklar; tek bir ASCII dışı karakter bile varsa tamamı 2 bayt olarak yönetilir
- String serileştirme performansı için string türüne göre ayrı algoritma sürümleri üretilip derlenir
- İşlem sırasında string örneğinin türü kontrol edilmek zorunda olduğundan, 2 baytlık bir string algılanırsa uygun 2 baytlık serileştirici durumu devralır
- Bu sayede string kodlamasına göre yol değiştirme yükü pratikte yok denecek kadar azdır
- Sonuçta 1 bayt ve 2 bayt tamponları ayrı ayrı oluşturulur, ardından en sonda basitçe birleştirilir
SIMD ile string serileştirme optimizasyonu
- JavaScript stringleri, JSON serileştirmesinde kaçışlanması gereken karakterler içerebilir
- Uzun stringler, SIMD donanım komutlarıyla (ARM64 Neon gibi) aynı anda birden çok bayt taranarak işlenir
- Kısa stringler ise SWAR yöntemiyle, genel amaçlı register'larda yapılan bit işlemleri sayesinde birden çok karakteri aynı anda işler
- Hangi yöntem kullanılırsa kullanılsın, çoğu durumda tüm string neredeyse hiç dönüşüm olmadan hızla kopyalanabilir
Express Lane (ultra hızlı yol) eklendi
- Fast Path içinde de property kontrolü gibi tekrarlayan işler olmadan yalnızca anahtar kopyalayarak serileştirme yapılabilmesi için Express Lane eklendi
- Nesnenin hidden class bayrağı kullanılarak, anahtarlarda Symbol bulunmadığı, hepsinin enumerable olduğu ve kaçış gerektirmeden serileştirilebildiği durumda nesne
fast-json-iterable olarak işaretlenir
- Aynı hidden class'a sahip başka bir nesne serileştirilirken ek kontroller olmadan doğrudan anahtar kopyalama yapılır
- Bu teknik
JSON.parse içinde de hızlı anahtar karşılaştırması için kullanılır
Daha hızlı double-to-string algoritması
- Sayıların stringe dönüştürülmesi de hem sık gerçekleşen hem de karmaşık bir işlemdir
- Mevcut Grisu3 algoritması Dragonbox ile değiştirilerek,
Number.prototype.toString() çağrılarının tamamında performans artışı sağlandı
Geçici tampon yapısının optimize edilmesi
- String oluşturulurken önceden tek ve kesintisiz bir tampon kullanılıyordu; yer yetmediğinde tüm içeriğin kopyalanması gerektiği için ek yük oluşuyordu
- Yeni yöntem parçalı (segmented) tampon yapısı kullanıyor; birden çok küçük tampon ihtiyaç oldukça birbirine ekleniyor
- Böylece alan yetersiz kaldığında tümünü kopyalamak yerine yalnızca yeni bir tampon ayırmak yeterli oluyor
Sınırlar
- Fast Path yalnızca basit veri serileştirmesinde çalışır
- Aşağıdaki koşullar karşılanmazsa genel yol kullanılır
- replacer veya space argümanları kullanılamaz (Pretty-Print veya dönüştürme yok)
- toJSON gibi özel metodu olmayan basit nesneler olmalıdır
- İndeks tabanlı property varsa yavaş yola geçilir
- ConsString gibi özel stringler işlenmez
- Yine de veri serileştirme, API yanıtı üretme, ayar önbellekleme gibi yaygın kullanım alanlarında optimizasyon etkisi otomatik olarak uygulanır
Sonuç
JSON.stringify için temel tasarımdan bellek ve karakter işlemeye kadar tüm alanlarda yaklaşım yeniden düzenlenerek JetStream2 benchmark'ına göre 2 katından fazla hız artışı sağlandı
- Bu iyileştirmeler V8 sürüm 13.8 (Chrome 138) ve sonrasında doğrudan deneyimlenebilir
Henüz yorum yok.