If you are interested in Yuzu, you're probably also interested in Ryujinx. In a departure from most advanced emulators (Yuzu, RPCS3, etc), Ryujinx is written in C#.
what a horrible language choice for an emulator, no wonder it under performs compared to Yuzu, ton of micro stutters, i bet it's due to the GC and the JIT compiler; on top of using more memory
just for clarity, cpu/audio emulation needs predictive performance, you can't have that with C# due to the managed nature of it
I don't know, the name implies they target the RyuJIT, which is a state of the art JIT compiler. I feel in general games should perform really well on a JIT since they are predominantly performance sensitive in a tight loop. Dolphin also has a JIT if I'm not mistaken. The alternative is to interpret which in theory should have worse performance (though in practice there's definitely exceptions to that rule).
I think it should be possible to achieve predictable performance, though it depends on the qualities of the JIT, it won't work if it's constantly recompiling or allocating stuff that needs to be garbage collected of course.
Glad this was flagged. A lot of people have a misconception of managed languages being slow compared to your regular ol' binary program, these days that couldn't be further from the truth. In traditional high performance C/C++ development you have to manually split your code into hot and cold paths, static analysis optimization can only go so far.
Do you want to inline this function in your loop? Yes and no, i.e. you might be taking up some valuable registers in your loop, increasing register pressure. Time to pull out the profiler and experiment, wasting your precious time.
Managed languages have the advantage of knowing the landscape of your program exactly, as __that__ additional level of managed overhead can help the VM automatically split your code into hot and cold paths, having access to the runtime heuristics of your program allows it to re-JIT your hot paths, inline certain functions on the fly, etc.
It's pretty common for game engines to disable background GC and explicitly call the GC only at certain times (e.g., between processing the current frame and before starting the next frame). Sometimes that can be done using the default GC and sometimes it requires a custom incremental GC.
Same idea applies to a JIT. Getting the best performance may require tuning the JIT to only run at certain times (e.g., before starting a level).
Unity uses C# for a certain layer but the engine itself isn't C#. They also do some work for ammortized multi frame GC.
That said, there's tons of games written in less than optimal languages for major portions of the game, like Naughty Dog games in the PS1/PS2 era used a lisp based language for a lot of things
Apart from what others have pointed out about Unity's engine code being C++ it also comes with support for IL2CPP which compiles the code to cpp which can be optimised.
We've used this on all Unity projects I've been part of and it really makes a difference in performance.
https://github.com/Ryujinx/Ryujinx
https://blog.ryujinx.org