.NET languages all compile to an intermediate language (MSIL).
As far as i know, during execution (and sometimes during other stages, which i am not fully knowledgeable about — NGEN), code is being JITted (Compiled from MSIL into actual machine code).
I am wondering if after JITting the code there are performance “penalties” coming from the fact that the code is executing on the CLR, or whether the code behaves “the same” as any other native code?
There are a number of performance differences:
The free store for managed objects is implemented as a stack, not a heap (except for the Large Object Heap), and is lower overhead than the heap used by most native allocators. But then you pay for garbage collection and compaction later.
The JIT can inline some calls that an AOT compiler would have to leave virtual (i.e. calls into other assemblies). But the AOT compiler can spend more time looking for optimization opportunities.
Theoretically, the JIT can use advanced instructions present on the particular CPU running the code (e.g. AVX). Still waiting for a JIT that actually makes good use of them, though.
AOT compilers can use profiling data to control layout of code memory. JIT compilers almost always emit functions into memory in the order they were compiled.