· kaynak Hacker News – Front Page (native)
NetWasm, C#'ı doğrudan WebAssembly'ye derliyor ve binary boyutunda Rust'ı geride bırakıyor
Bağımsız bir .NET toolchain'i olan NetWasm, C#'ı doğrudan bağımsız WASI WebAssembly bileşenlerine derliyor ve kendi print-42 benchmark'ında 47.798 baytlık binary ile Rust'ın 53.635 baytını geçiyor.
WebAssembly için bağımsız bir .NET stack'i
NetWasm, bağımsız olarak geliştirilmiş bir .NET-for-WebAssembly toolchain'i — bir derleyici, CoreLib, runtime ve SDK'dan oluşan — ve C# ile .NET CIL'i doğrudan WebAssembly'ye dönüştürüyor. Hacker News'in ana sayfasına çıkan projenin GitHub deposuna göre çıktı, masaüstü CLR, Mono, dotnet.js veya uygulama DLL'leri taşımıyor: yayımlanan Wasm bileşeninin kendisi programın ta kendisi. Proje kendini, kasıtlı olarak daha küçük bir sözleşmeye sahip yeni bir .NET platformu olarak konumlandırıyor; Wasm sandbox'ına yerleştirilmiş masaüstü .NET olarak değil.
Dikkatleri çeken iddia ise, 42 sayısını yazdıran basit bir program için, precise garbage collector'ıyla NetWasm 0.8.0'ın Rust'tan daha küçük bir bağımsız artifact üretmesi.
Karşılaştırmanın ardındaki sayılar
Her iki artifact de boyut odaklı ayarlarla derlenmiş bağımsız WASI Preview 2 bileşenleri. NetWasm'ın binary'si 47.798 bayt iken, boyut odaklı bir profilde derlenen Rust 1.95.0 için bu sayı 53.635 bayt — ham haliyle %10,9, Brotli-11 sıkıştırmasından sonra ise %20,4 daha küçük (13.501'e karşı 16.963 bayt). Kritik nokta şu: NetWasm'ın rakamı runtime'ını ve garbage collector'ını da içeriyor.
Bağlam için, dokümantasyonda Kotlin 2.4.0 wasmWasi'nin 79.293 bayt ve TinyGo 0.39.0'ın 93.043 bayt olduğu da listeleniyor; ancak ikisinin de farklı runtime sınırlarıyla WASI Preview 1 bağlamlarında çalıştığı belirtiliyor — örneğin Kotlin'in garbage collection'ı host engine tarafından sağlanıyor. Proje, bunun tek bir iş yükü ve profil için ölçülmüş bir sonuç olduğu, diller genelinde bir boyut sıralaması olmadığı konusunda açık.
Binary nasıl küçük kalıyor
Roslyn C#'ı CIL'e derliyor, NetWasm ise programın erişilebilir kısmını doğrudan Wasm'a derliyor; generic'leri özelleştiriyor ve yalnızca gerçekten kullanılan runtime desteğini link ediyor. Dokümantasyon birkaç tasarım kararını öne çıkarıyor: erişilemez kodu, import'ları ve runtime özelliklerini dışlayan closed-world derleme; birçok masaüstü runtime varsayımını düşüren daha küçük bir platform sözleşmesi; geniş kapsamlı runtime reflection'ın olmaması — runtime tip adları, dinamik assembly yükleme ve dynamic anahtar kelimesi profilin dışında; runtime keşfi yerine JSON, dependency injection, WIT ve native interop için üretilmiş sınırlar; timezone veritabanları gibi opt-in veriler; ve yalnızca seçilmiş tek bir garbage collector'ın link edilmesi.
Geliştiriciler dört allocation stratejisinden birini seçiyor. Varsayılan olan Compact, boyutu önceleyen, precise, taşıma yapmayan bir mark-and-sweep collector — "compact" burada implementasyonun boyutuna işaret ediyor, heap compaction'a değil — ve conservative tarama yerine derleyicinin yayımladığı kökleri izliyor. Dokümandaki strateji tablosu, tek seferlik Bump seçeneğini ham 43.864 baytla, throughput odaklı NetWasmGC'yi ise 50.855 baytla listeliyor.
Mono AOT'ya karşı performans iddiaları
0.10.0 sürümünden itibaren proje, allocation ve garbage-collection benchmark'larının, aynı C# kaynağından derlenmiş ve aynı Wasmtime tarafından çalıştırılan Mono AOT'dan daha hızlı çalıştığını bildiriyor. Wasmtime 49.0.3 altında bir Apple M1 Max'te 15 çalıştırmanın medyanları olarak, tam bir transaction için 43,9 ms'ye karşı Mono AOT'nin 59,1 ms'si (%26 daha az), tutulan object graph için 8,8'e karşı 14,2 ms ve UI churn için 17,6'ya karşı 29,1 ms listeleniyor. NetWasmGC ayrıca ilk iki iş yükünde masaüstü .NET 11'in JIT'ini geçtiğini bildiriyor (49,9 ve 9,7 ms); UI churn'de ise JIT 8,6 ms ile kazanıyor; masaüstü NativeAOT üçünde de en hızlısı olmayı sürdürüyor.
Blazor açığı — uyarılarla birlikte
AOT, managed trimming, IL stripping ve diğer boyut optimizasyonları etkinleştirilmiş bir print-42 Blazor WebAssembly uygulaması için dokümantasyon, .NET 10'da 12.276.684 bayt (NetWasm'ın 257 katı) ve .NET 11 RC1'de 15.289.241 bayt (320 kat) listeliyor. Projenin kendisi de bunun bir console bileşenini boş bir UI uygulamasıyla karşılaştırdığını ve eşdeğer çerçeve karşılaştırması olmadığı konusunda uyarıyor.
İş akışı ve mevcut sınırlar
Projeler sıradan dotnet CLI üzerinden derleniyor: .NET SDK 10.0.303 veya daha yeni bir sürüm yüklendikten sonra şablonlar normal şekilde restore edilen, çalışan ve yayımlanan uygulamalar oluşturuyor; yayımlanan bileşen ise Wasmtime gibi bir WASI Preview 2 host'unda çalışıyor. Hello world'ün ötesinde platform; C# 15 desteği, sayfalar ve Web Worker'lar için tipli JavaScript modül export'ları, üretilmiş C ABI marshalling ile Wasm .a arşivlerinin link edilmesi, WIT binding'leri, genel reflection olmadan expression tree'ler, paketlenmiş LINQ, HTTP, JSON, XML ve Regex kütüphaneleri, TUnit ve VSTest entegrasyonu ve wasm64 destek iddialarında bulunuyor. Kütüphaneler netwasm0.1 profili ile masaüstü net10.0'ı çoklu hedefleyebiliyor. SDK, sabitlenmiş Node, LLD ve Binaryen araçlarını NuGet üzerinden restore ediyor; dolayısıyla ayrıca Emscripten, Git veya Python kurulumu gerekmiyor.
Sınırlar gerçek. NetWasm henüz 1.0 öncesi bir durumda; kaynağı, paketleri, hedef profil ve ABI sözleşmeleri minor sürümler arasında değişebilir. Runtime reflection, dynamic, runtime assembly yükleme ve managed threading profilin dışında; genel dosya API'leri, raw socket ve subprocess'ler henüz uygulanmadı. Mevcut NuGet paketleri yalnızca erişilebilir kodları desteklenen profile sığıyorsa çalışıyor.
Neden önemli
Binary boyutu web'de yükleme sürelerini, edge'de ise cold start'ları belirliyor — ve bu alan büyük ölçüde Rust, C ve Zig gibi runtime'sız dillere ait olageldi. NetWasm'ın rakamları bağımsız ölçümler altında doğrulanırsa, garbage collector'lı bir .NET dilin — runtime ve GC dahil — Rust'tan daha küçük bileşenler teslim etmesi, küçük Wasm'ın managed runtime'lardan vazgeçmek anlamına geldiği varsayımına meydan okur. Uyarılar da ciddiye alınmalı: bunlar projenin kendi benchmark'ları, minimal bir iş yükü üzerinde; ve boyut kazançları kasıtlı olarak daraltılmış bir API yüzeyinden geliyor. Ama closed-world derlemenin .NET için neler yapabileceğinin bir gösterimi olarak, dikkat çekici bir veri noktası.
- #webassembly
- #csharp
- #dotnet
- #compilers
- #wasi