C# di fatto viene compilato in bytecode MSIL (una specie di codice macchina per una "CPU virtuale" di più alto livello rispetto alle CPU vere); al momento dell'esecuzione, il bytecode MSIL viene JIT-compilato in codice macchina "vero" della CPU su cui sta girando il .NET Framework.
Discorso velocità: dipende. La compilazione "just in time" ha meno tempo rispetto ad un compilatore "tradizionale" per provare ad ottimizzare in maniera aggressiva (visto che c'è lì l'utente che attende che il programma parta), ma ha una serie di vantaggi derivanti dal conoscere esattamente l'ambiente in cui viene eseguito il codice, per cui in linea di principio può emettere codice più efficiente per la specifica CPU su cui gira, o fare tracing/profiling al volo del codice per individuare i punti più "caldi" e ottimizzarli in base ai percorsi di codice più frequenti (da questo punto di vista ho visto fare cose egregie a LuaJIT - dal bytecode di un linguaggio estremamente dinamico come Lua riesce spesso a cavare fuori codice macchina che va a velocità dello stesso ordine di grandezza dell'equivalente C).