2

IL2CPP.exe is a Unity utility for converting C# IL code to C++. My question is: can this executable be used outside of the Unity game-development environment as a general-purpose tool for converting any .NET application (not just games) to a high-performance native executable?

Although I do know some C++, It would certainly be nice to be able write all kinds of programs in a language I am comfortable and fluent with (C#)......whether they be audio/video/music-production DAWs or OS-level security/forensics tools or machine-learning platforms or anything else that's resource-intensive.......and know that they will run as efficiently as an app written in straight C++.

Cade Bryant
  • 737
  • 2
  • 7
  • 19

1 Answers1

4

Short answer: NO

IL2CPP is tightly connected to the Unity environment and it's not possible to use it outside of Unity. You would need to write your own converter(?) to do such a thing.

Longer answer

IL2CPP doesn't do any magic in terms of performance improvement. Comparing C++ with C# with IL2CPP code should give (almost - more below) no performance benefit.

IL2CPP is performant compared to C# code written for Unity specifically for few reasons that have nothing to do with C++.

Why Unity is unique and needs IL2CPP:

  • Unity API is very heavily reliant on main thread performance, as the whole Unity API was written almost 10 years ago, where 2 Core CPUs were top-notch and everyone believed that we will have 20-50GHz single-core CPUs by now.
  • Unity makes a lot of assumptions that you will use their API for everything, begging from IO to Threading and GPU access, which is heavily bound to C++ core.
  • Unity needs to be wrapped with Unity objects (MonoBehaviours and GameObjects) to be used for almost anything, you cannot write your own native anything. (This is a simplification)
  • Unity is written in C++, so it needs to do something very similar to Marshalling, and it's not very efficient.

So why IL2CPP?

  • Unity cannot convert its already very legacy backend (Mono) and its legacy API to be multithreaded since Mono have a lot of assumptions about your code that are not easily convertible to "simple" unity API.
  • Unity core is written in C++, so they are eliminating any form of Marshalling all together by skipping Mono "translator".
  • IL2CPP converts highly inefficient C#, single-threaded code to multithreaded C++, where possible, and it does this by analyzing IL code.

Is it worth converting other C# to C++?

No! Compare any arbitrary, optimized C# code that was precompiled by AOT to (modern) C++. You should get the same performance! Identical I would say.

C# is compiled to IL (Intermediate Language) which as the name suggests is Intermediate. It's converted in runtime to Native Binary code (only when needed), that is what C++ is compiled into. You can force this conversion by skipping IL generation by running Ahead of Time compilation (AOT).

The ONLY thing that your C# code will be less performant is when you are abusing GC's ability to clean up after you.

Tomasz Juszczak
  • 2,276
  • 15
  • 25
  • 1
    "*modern C++ have GC as well*" Not in the language itself. There exist libraries like Boehm GC but those are not part of the standard. – dxiv Mar 07 '21 at 21:58
  • @dxiv I cannot find relevant information, but I thought they added GC to C++11 via `shared_ptr`. – Tomasz Juszczak Mar 07 '21 at 22:14
  • 2
    @TomaszJuszczak [`shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr) is a [`RAII`](https://en.cppreference.com/w/cpp/language/raii) wrapper, nothing GC about it. – dxiv Mar 07 '21 at 22:20
  • Fair enough description of it, I guess. Have you looked at DOTS btw? Is kinda a refactor of the core for parallelizing and otherwise optimising things, with data in arrays instead of objects kind of. – antont Sep 29 '21 at 20:06
  • @antont DOTS is built on top of the IL2CPP core. They are using an existing stack that they use for "normal" unity code and sprinkle some more under the hood magic to it. You can do the same thing in C# if you wish to write your own engine. Just keep all the data in multiple arrays, grouped by object type and process every group in parallel and you have DOTS in C#! Just remember to not allocate memory all the time so that GC do not have to work for you :) – Tomasz Juszczak Sep 29 '21 at 20:40
  • I would say that besides abusing the GC, a naive programmer can make C# slower by, for example, using managed code to iterate large arrays rather than using unsafe pointers, etc. And on the extremely rare occasion that you do find something that just can't be optimized, you can always put it in a C++ DLL and call it from your C# code. – Digiproc Dec 15 '22 at 13:00
  • @Digiproc If you need to micro-optimize CLR than you can do more bad then good when iterating using pointers instead of managed looping. If you are memory conscious and do a `for` instead of `foreach` then you should be fine when it comes down to performance and be on pair with C++ looping performance wise. Even in managed C# environment. – Tomasz Juszczak Dec 15 '22 at 16:06
  • "and everyone believed that we will have 20-50GHz single-core CPUs by now." In 2011, most people in tech already know this was never going to be a thing. Intel already tried (and failed) with his NetBurst architecture about 20 years ago. – tigrou Mar 27 '23 at 12:24
  • @tigrou It looks like not everyone got the memo ;) – Tomasz Juszczak Mar 27 '23 at 17:09