- Runtime Mono yang digunakan Unity menunjukkan kecepatan eksekusi yang jauh lebih lambat dibandingkan .NET modern, dengan kasus di mana kode C# yang sama bisa berbeda performa hingga 15 kali lipat
- Pada kode game nyata, eksekusi Unity berbasis Mono memerlukan 100 detik, sementara eksekusi kode yang sama di .NET terukur 38 detik, sehingga sangat memengaruhi efisiensi debugging dan pengujian
- Bahkan dalam mode Release, Mono membutuhkan 30 detik dan .NET 12 detik, sehingga perbedaan performa lebih dari 2,5 kali tetap bertahan bahkan di lingkungan yang sudah dioptimalkan
- Penyebabnya mencakup kompilasi JIT Mono yang tidak efisien dan kegagalan inlining, penyalinan memori berlebihan, dan hal lain yang kontras dengan optimisasi JIT CoreCLR modern di .NET
- Jika Unity menyelesaikan modernisasi .NET berbasis CoreCLR, peningkatan performa besar dimungkinkan baik pada game maupun editor, dan ini diperkirakan akan menghapus pajak performa tersembunyi di semua proyek Unity
Latar belakang penggunaan Mono di Unity
- Unity menggunakan framework Mono untuk menjalankan kode C# sejak 2006
- Saat itu Mono adalah satu-satunya implementasi .NET multiplatform, dan bersifat open source sehingga bisa dimodifikasi oleh Unity
- Sejak 2014 Microsoft merilis .NET Core sebagai open source, lalu meluncurkan .NET Core 1.0 pada 2016
- Setelah itu, ekosistem .NET berkembang pesat lewat kompiler Roslyn, JIT baru, peningkatan performa, dan lainnya
- Pada 2018, para engineer Unity mengungkapkan bahwa mereka sedang mengerjakan porting CoreCLR, dengan harapan peningkatan performa 2 hingga 10 kali dibanding Mono
- Namun hingga akhir 2025, menjalankan game berbasis CoreCLR masih belum memungkinkan
Kesenjangan performa Mono dan .NET
- Kode simulasi dari proyek Unity dijalankan di luar Unity dengan .NET untuk dibandingkan secara langsung
- Lingkungan Unity/Mono: 100 detik, lingkungan .NET: 38 detik (berdasarkan mode Debug)
- Dalam mode Release, Mono 30 detik dan .NET 12 detik, sehingga kesenjangan tetap ada
- .NET juga unggul dalam optimisasi multithread, misalnya mampu membuat peta 4K×4K dalam waktu kurang dari 3 detik
- Penyebab utama adalah pembuatan kode yang tidak efisien di Mono, yang bahkan pada loop sederhana dapat menimbulkan selisih kecepatan 15 kali
Perbandingan assembly: Mono vs .NET
- Hasil perbandingan assembly x64 yang dihasilkan dari kode uji yang sama menunjukkan bahwa
- JIT .NET memindahkan loop invariant ke luar loop (hoisting) dan hanya melakukan operasi register seminimal mungkin
- Mono justru mengulang penyalinan memori dengan puluhan instruksi mov, serta mengalami inlining yang tidak efisien sehingga performa turun
- Waktu eksekusi loop pengulangan
int.MaxValue
- .NET: 750ms, Mono: 11,500ms, Unity Editor (Debug): 67,000ms
- Mono berulang kali melakukan perpindahan memori dan operasi perbandingan yang tidak perlu di dalam loop
Makna adopsi CoreCLR
- CoreCLR menyediakan fitur modern seperti JIT terbaru, API Span<T>, optimisasi SIMD, dan dukungan instruksi hardware
- Fitur-fitur ini membuka kemungkinan peningkatan performa tambahan lebih dari 2 kali
- Kompiler Burst milik Unity menghasilkan kode native berbasis LLVM, tetapi memiliki batasan pada fitur C#
- JIT modern CoreCLR dapat memberikan performa mirip Burst dengan lebih sedikit batasan bahasa
- CoreCLR juga mendukung AOT (ahead-of-time compilation) untuk meningkatkan kecepatan startup dan menangani platform yang membatasi JIT (seperti iOS)
- Namun, Unity masih menyatakan akan tetap mempertahankan IL2CPP
Kesimpulan: Unity perlu modernisasi .NET
- Mono menunjukkan performa eksekusi 1,5 hingga 3 kali atau lebih lambat dibanding .NET modern, dan ini menjadi biaya tersembunyi bagi semua proyek Unity
- Efek yang diharapkan dari adopsi CoreCLR
- Peningkatan performa runtime, build iteratif yang lebih cepat, GC yang lebih baik, penghapusan domain reload, porsi managed code yang lebih besar
- Roadmap Unity 6.x mencakup .NET Modernization, tetapi dijadwalkan untuk setelah 2026
- Jika dukungan CoreCLR selesai, hal itu dapat memberikan lompatan performa nyata bagi developer Unity maupun pemain
- Untuk saat ini, keterbatasan Mono masih menjadi bottleneck performa bagi seluruh ekosistem Unity
13 komentar
Ah... sepertinya Mono masih berbasis legacy .NET framework...
Ini bukan game, tetapi saya sedang memigrasikan aplikasi keuangan WinForm sekitar 100 ribu baris dengan .NET4.8 + LINQ to SQL + WinForm ke .NET10 + Entity Framework, dan terasa jelas jauh lebih cepat. Waktu komputasi yang tadinya 10 detik bahkan bisa turun menjadi 3 detik!
Akan bagus jika kompatibilitas NuGet juga ditambahkan (atau mungkin saya yang kurang paham soal Unity?)
Memang bukan dukungan resmi, tapi ada proyek open source bernama NuGetForUnity.
Secara teori, paket NuGet yang ditargetkan ke .NET Standard 2.0 memang bisa dipanggil dan digunakan juga di lingkungan Unity... tapi sepertinya tetap ada cukup banyak hal yang terasa kurang nyaman.
https://learn.microsoft.com/ko-kr/dotnet/…
Memang benar, tapi saya kurang paham kenapa harus membandingkan performa editor... Paling tidak, kalau mau dibandingkan mestinya bawa hasil dari build debug? Atau jangan-jangan kalau begitu malah jadi kurang meyakinkan? Di sisi lain, baik IL2CPP maupun Mono sama-sama terasa seperti teknologi yang sudah ketinggalan zaman.
Pada proyek besar, performa editor juga penting karena sangat menggerus pengalaman pengembangan. Membuka editor lambat, impor aset juga lambat, dan loop debugging/pengujian pun lambat...
Ah... tentu saja itu juga penting. Saat pertama kali membacanya, menurut saya penulis artikel tampaknya ingin membahas hal yang lebih mendasar, yaitu kecepatan eksekusi kode. Seperti yang Anda katakan, memang benar bahwa Unity juga lambat pada editor, lambat saat impor, dan keseluruhan loop pengujiannya juga lambat...
Senang sekali melihat ada tulisan tentang Unity.
Saya membacanya dengan baik.
Kalau ini berhasil diterapkan, optimisasi game indie yang bertebaran sepertinya mungkin akan jadi lebih baik...
Sebagai alasan lain mengapa Mono harus dimodernisasi ke CoreCLR, saya pikir Unity kemungkinan tidak punya kapasitas atau kemauan besar untuk berinvestasi pada peningkatan performa Mono. Saya rasa sudah benar kalau warisan dari era .NET Framework dibereskan secepat mungkin. :-D
Dan saya juga berharap dipertimbangkan bahwa mulai .NET 10, masalah yang dulu ingin mereka selesaikan dengan IL2CPP kini sedang ditangani secara tepat, meski dengan arah pengembangan yang berbeda, yaitu melalui Native AOT.
Tentu saja, keterbatasannya adalah tidak dihasilkannya kode C++ yang bisa diedit di tengah proses, tetapi pada akhirnya kemampuan untuk menghasilkan biner native tanpa terjadinya Just-In-Time telah makin matang sejak .NET 8 dan semakin matang lagi di .NET 10.
Karena itu, saya rasa terus menunda modernisasi ke CoreCLR bukanlah pilihan yang baik bagi Unity. Atau mungkin penggantian dengan beralih sepenuhnya ke bahasa atau fondasi yang sama sekali berbeda bisa jadi lebih efektif juga!
> Unity kemungkinan tidak punya cukup kapasitas atau kemauan untuk berinvestasi dalam peningkatan performa Mono
Saya juga sangat setuju dengan ini...
Komentar Hacker News
Ada beberapa bagian yang terasa seperti ditulis oleh seseorang yang pengalamannya dengan pengembangan Unity masih terbatas
Singkatnya, alasan pengembang Unity menantikan pembaruan ini bukan terutama peningkatan performa, melainkan akses ke fitur bahasa modern. Dan meminimalkan GC saat runtime atau mengakalinya dengan memori unmanaged dan DOTS sudah menjadi praktik umum
IL2CPP tidak lebih dari generator kode berkualitas rendah yang mengubah .NET IL menjadi C++, lalu bergantung pada compiler optimasi
Ini bisa dilihat dari struktur internal IL2CPP di blog Unity
Burst/HPC# juga mengikuti tren seperti ECS atau SoA, tetapi performanya masih kalah dari C++ yang ditulis dengan baik atau C# CoreCLR
Selain itu, teknologi ini tertutup dan khusus Unity, jadi tidak bisa dipakai di luar sana. Unity selalu memasarkan dengan benchmark yang membandingkannya dengan Mono yang lambat
Pada akhirnya Unity juga terpaksa menerima CoreCLR, dan saat itu mereka akan sadar akan kenyataan bahwa kode C# biasa lebih cepat daripada kode rumit yang mereka miliki sekarang
Alasan kami tidak memakai IL2CPP adalah karena loading DLL saat runtime, reflection, packing struct dengan FieldOffset, dan hal-hal serupa tidak kompatibel dengannya
Modder bisa memperluas fitur lewat IL injection, dan hasilnya justru mempercepat pengembangan
Saya juga tidak menyukai Burst dan HPC# karena kompleksitas serta banyaknya batasan. Perbedaan performa antara Mono dan .NET terasa makin menyebalkan karenanya
Profiling di editor juga tetap berguna bagi kami karena menunjukkan peningkatan performa dengan rasio yang mirip dengan build nyata. Sebagai gantinya, profiler bawaan Unity kurang akurat sehingga kami memakai sistem pelacakan buatan sendiri
GC masih menjadi masalah. Pemrosesan string atau UI menghasilkan garbage di setiap frame. Dengan pindah ke CoreCLR, kami berharap API yang lebih baik dan moving GC bisa mengurangi masalah fragmentasi memori
Asset Store sangat bagus, tetapi engine-nya sendiri terasa belum benar-benar rapi.
Scripting berbasis Mono secara struktural rumit untuk dipindahkan ke CoreCLR
Jika Unity sungguh ingin memperbaiki Core-nya, mereka harus mendesain ulang seluruh editor seperti Blender 3.x.
Saat ini rasanya seperti UI tahun 1999
Banyak plugin dan tool berhenti di tahap “0.x-preview”, lalu 5~10 tahun kemudian tidak lagi berfungsi atau tenggelam di bawah aset baru
Karena itu sekarang saya hanya memakai versi 1.0 ke atas. Kalau tidak, kita jadi bergantung pada plugin yang ditinggalkan dan akhirnya harus melakukan porting ulang
Unity, pengembang, dan pengguna semuanya rugi
Secara internal mereka kurang punya rasa nyata soal pembuatan game karena gagal dalam pengembangan game mereka sendiri
Mereka hanya menambahkan fitur yang diminta, tanpa visi yang konsisten
Jika performa penting, lebih baik memanggil Vulkan secara langsung, dan jika portabilitas lebih penting maka gunakan WebGPU
Karena implementasinya berbeda di tiap browser, ada overhead, tetapi itu bisa diatasi jika WebGPU disediakan di level driver OS
Sebaliknya, Godot menyediakan building block yang sederhana dan bermakna, sehingga kita bebas membuat apa yang diinginkan
Asset Store juga mengalami hal serupa; masalah kompatibilitas versi membuat perawatannya sulit, dan kebanyakan akhirnya menjadi aset yang terbengkalai
Ketika Unity mengakuisisi aset yang berguna, integrasinya pun tidak dilakukan dengan baik, sementara aset pesaing menghilang
Sementara itu Unreal Engine menyediakan fungsi-fungsi seperti ini di tingkat bawaan engine
Unity juga tidak punya rencana untuk memasukkan GC yang lebih baik ke IL2CPP
Jika editor berbasis CoreCLR dirilis, bisa jadi justru editor lebih cepat daripada build
Diskusi terkait: Unity CoreCLR dan modernisasi .NET
Jika incremental GC bekerja dengan baik, masalah stutter juga tidak akan terlalu besar
Karena C# sendiri kini pada dasarnya sudah sangat cepat, Unity harus benar-benar memusatkan seluruh kemampuannya pada transisi ini
Tim kami butuh beberapa bulan untuk pindah dari .NET Framework 4.7.2 ke .NET 6, dan setelah itu upgrade ke versi LTS berikutnya cukup beberapa jam saja
Terus tertunda, dan para pemimpinnya pergi
Sebagai alternatif saya merekomendasikan engine Stride berbasis .NET 10. Tidak ada overhead boundary seperti di Unity
Godot memang open source, tetapi dukungan C#-nya tidak stabil, dan jika build Web tidak jalan maka tidak cocok untuk game jam
Kita butuh solusi sandbox sungguhan dengan dukungan GPU
Prioritas terus berubah, kebutuhan direvisi, dan pekerjaan berulang
Para pengembangnya tetap hebat, tetapi daya dorong yang konsisten kurang ada
Rewriting sebesar ini adalah keputusan berisiko tinggi bahkan dari sudut pandang CEO
Hasilnya performa meningkat besar, dan dengan berkurangnya ketergantungan pada engine, perawatan kode juga jadi lebih mudah
Dengan hanya mengekspos konsep Unity di tempat yang perlu dan memaksa boundary lewat pengujian, saya benar-benar merasakan nilai dari pemisahan logis
Jika ada akses root, lalu dikombinasikan dengan tool jaringan seperti WireGuard atau Tailscale, itu juga sempurna sebagai server portabel
Dengan GC baru di .NET 10, stutter dalam game juga hampir akan hilang
Saat ini saya streaming game dari PC utama ke ponsel dengan Sunlight + Moonlight.
Berkat layar OLED refresh rate tinggi, konsumsi baterainya juga rendah
Memang bukan .NET SDK, tetapi karena runtime Mono disertakan di aplikasi, rasanya kurang lebih mirip
Keunggulan lintas platform Mono sebenarnya sudah hilang, jadi saya tidak paham kenapa mereka masih mempertahankan hack rumit seperti IL2CPP
Bertahun-tahun modifikasi non-standar telah menumpuk, sehingga kalau bukan perusahaan besar akan sulit mengoptimalkannya lagi dari nol
Untuk proyek sebesar ini saya kira 1~2 tahun seharusnya cukup