Hacker News new | ask | show | jobs
by p1necone 1919 days ago
The problems with GC'd languages are very exaggerated. I'm not surprised at all that this is performant in C#.
4 comments

For game dev (and emulators!), the non-deterministic behavior of GCs can cause a lot of trouble, mainly because you have a fixed frame budget. That’s why it’s usually easier to just use a language where you can finely control when and where allocations take place.

I’m sure there are techniques to work around this, but you’d then usually have to leave behind the “idiomatic” area of the language you’re using.

Yes, In C# you have to leave the idiomatic side somewhat to get the most performance. Though this is getting better in latter versions of C#, in which you get more low level coding features. But for me the fun part is doing exactly that. Coding as close to the metal as possible, leaving the "safe" side of C# but still using the Quality of Life features that C# offers compared to C++. That for me makes C# my favorite language ever.
I like C# and use it a lot, but for performance sensitive apps I need SIMD. Microsoft is making improvements, but not enough, still a long way to be comparable to C++. Currently, they don't support NEON on 32-bit ARM, and have performance issues in the JIT: https://github.com/dotnet/runtime/issues/13811
C# is one of the most popular languages to write games in (with Unity), so it can't be that bad. I'd expect it to perform well if you only allocate short-term objects, since it can do escape analysis and figure out they can all go on a stack, but I don't know how Mono's GC works.
C#, or more specifically the .NET VM (goes for F# and VB too) has a lot more features that make it a lot easier to avoid GC events than in the past. Managing memory especially across interop with Span support means a lot less copying from managed to unmanaged memory as an example which would help a lot with games that often need to invoke operating system libs/drivers.
.NET 5 further improves upon an already very capable GC:

https://devblogs.microsoft.com/dotnet/performance-improvemen...

Most notably:

> When running with the “Server GC”, a thread per core is involved in collections, and as threads finish their allotted portions of the marking work, they’re now able to “steal” undone work from other threads in order to help the overall collection complete more quickly.

It's mainly the horrible "enterprise" culture around them, which leads to ridiculous abstraction bloat and the associated increase in resource consumption.