I have always thought that UE is faster than Unity as UE uses C++ and Unity C#. C++'s philosophy seems to be broken here, which is you pay for the things you use. Now reflection and garbage collection is added. So why should UE4 be faster if they made from C++ another C#?
-
2Reflection isn't very expensive from a high-level entity standpoint, and C++'s speed over C# doesn't merely boil down to reflection. A great deal of it has to do with memory allocation, e.g. That said, just from a reflection standpoint, UE 4 isn't using it for, say, the lowest-level UDTs. It's still sort of pay for what you use -- they're not adding it uniformly to every single `struct/class` in the entire system. – Nov 29 '15 at 17:46
-
1Maybe put broadly, C++ still lets you drill down to the lowest-level kind of C-style code -- the sequential/fixed memory allocator just dealing with raw chunks of bits and bytes, e.g. UDTs can be allocated contiguously, even when they aren't allocated all at once. Those high-level ECS-style interfaces are often not the most performance-critical parts -- it's those tight loops, a relatively small section of the codebase, where we benefit from drilling down to the lowest-level tuned native code. – Nov 29 '15 at 17:53
-
1That might then lead to: "why not take C# and implement the small performance-critical parts in C++?" And that could be a very legit strategy -- one language for productivity, another for performance. The difficulty is that, even though the performance-critical sections are small, it can often be a bit easier to do it all in one language... to take something like C++ and add concepts like properties that can be queried through reflection, still being able to avoid such costs for the critical areas... vs using a language which has this uniformly and look to another language for speed. – Nov 29 '15 at 18:11
1 Answers
I'm not sure if this is a complete answer, I have attempted to show why both Unreals reflection and it's GC do not mean it has to be as slow as C#.
Reflection
C# has a very powerful reflection system that allows you to do a number of crazy things at run time (constructing generic classes, generating functions). This is because C# is compiled into a byte code which is the Just-in-time (JIT) compiled in to the machine code that gets executed. A lot of the reflection is implemented in the common language interface (CLI)1. This comes at a speed expense - the code has to be compiled at run time and as a result can undergo less aggressive optimisations (less time to do them as user is waiting for the program to start).
The reflection system in Unreal, on the other hand, is implemented at compile time by generating a load of code that is then also compiled by the same C++ compiler. Of course if you make extensive use of this reflection system (calling functions by name, accessing properties dynamically), it will be slower than if you didn't and you will lose at lot of compile time optimisations on that code. But if you don't and you just occasionally get the type of a class, then the main cost you will pay for the reflection system is simply the size of your binary (and the compilation time).
Garbage Collection
I don't know the details of Unreals Garbage Collection system, so this section may be incomplete. Typically, the reason why game developers care about GC (or the lack thereof) is:
- GC'd languages can be wasteful when you have a lot of rapid allocations/deallocations2. In C++ you can allocate on the stack (which is faster3) when you know the data is going to be thrown away shortly.
- You (the developer) don't know when a GC will be triggered which can cause a break in the smooth frame rate. Normally, developers prefer to control when garbage collection happens.
Unreal can avoid the first problem as only UObject
s are GC'd anyway. This means you can still use normal classes without worrying about the garbage collector and happily allocate on the stack when appropriate.
For the second point, I'm not certain how GC is implemented in Unreal but it is certainly imaginable that they have considered this and have a way to side-step the hitches.
In conclusion, Unreal is still able to use features that allow C++ to be faster than C# (more aggressive optimisation, stack allocation) even with the basic version of reflection and GC that it has.
1: How is reflection implemented in C#?