What is Common Language Runtime (CLR) and why should I learn about it?
Chronicles of .NET Runtime - Part 1
Hi! đ
Iâve been talking about it for a while now. Given that the last article on C++ and memory allocation went out yesterday, itâs time to start a new chapter and new deep-dive series.
Before I do, Iâd like to take a moment and reflect on one thing. And this is something that has been hanging over my head for a while now. If you are just casually scrolling through Bitesized articles, youâd probably think something along the lines of âwow, this guy makes context switches like itâs nothing!â. In a way, youâd be right - I started writing about SQL Serverâs Storage Engine Internals, then switched to Containers, then spent some months on DB Indexes, before finally moving to C++ and Memory Allocation. Wanna know how that works and feels?
It sucks. And it scares the shit out of me. Honestly. It is exciting, for sure, because I get to explore cool new things that Iâm really interested in, but trust me - itâs scary! Starting ANYTHING new is always scary.
But hereâs the gist - I learned that after two or three articles it becomes a breeze and then it just starts flowing. Really. So I just need to survive to break the ice of the new topic and then Iâm sure it will get easier :)
Anyway, I just wanted to share those thoughts with you. Back to the original topic - CLR. As usual, the infographic first and then we go with some more detailed explanation!
I hope you found that useful :)
Letâs start from the beginning - do you need to know about CLR in order to use C# (or any other .NET based language)? No.
So why SHOULD YOU spend time on it? In my opinion - for the same reason you decide to learn anything - once you understand the internals, you get a whole new perspective on how to write more performant and reliable code.
Back to the topic, though. So, whatâs the Common Language Runtime (CLR )? Well, itâs the Runtime Engine for .NET. Just like JVM is for Java. It makes your .NET code actually DO stuff. But thereâs a lot more to it.
All your .NET code compiles into something that is, these days, referred to as Microsoftâs Intermediate Language (MSIL). Hereâs a very simple app:
namespace SampleCSharpApp2
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
And hereâs the MSIL code that was generated for it (hint: .NET bundles an app called ILDASM.exe - an IL Dissasembler; search for it in your .NET directory):
.class private auto ansi beforefieldinit Program
extends [System.Runtime]System.Object
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method private hidebysig static void '<Main>$'(string[] args) cil managed
{
.entrypoint
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldstr "Hello, World!"
IL_0005: call void [System.Console]System.Console::WriteLine(string)
IL_000a: nop
IL_000b: ret
} // end of method Program::'<Main>$'
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Program::.ctor
} // end of class Program
If youâve never encountered it before - thatâs OK. It might take a moment or two to get adjusted to it. What you are looking at is disassembled MSIL code :) It looks like assembly, but itâs way more readable and understandable. Well, for contrast, hereâs an actual assembly code for the same thing:
You have to agree that MSIL is a âbitâ more understandable, right?
Anyway, weâll talk lot more about MSIL in the upcoming articles. And if you havenât subscribed already, nowâs a good time to do so:
The whole point of MSIL and CLR is that you can run it on any architecture and any platform. And thatâs made possible by the fact that MSIL is being interpreted by CLR, which takes those instructions, compiles them to native-code for the target platform (e.g. if you are executing the code above on Linux, itâd be compiled to Linuxâs native code) and executes them. This process of compiling just before executing is called JIT Compilation (Just In Time Compilation). It has some pros & cons but weâll also spend some time discussing that in future articles. Whatâs important to remember for now is that CLR compiles the code to machine-readable language, whereas Java interprets the code and emulates it through Javaâs VM. Again, donât worry too much about it for now - itâll become more clear as we progress.
Whatâs uniquely cool about MSIL is that, strictly speaking, you are NOT limited to C#, F#, VB, etc. As long as you write a program that takes ANY source code (e.g. Python, PHP, C++, etc.) and converts it to MSIL - you can have it run on CLR. And people actually did just that:
IronPython compiles Python to CLR
PeachPie compiles PHP to CLR
Managed C++ compiles C++ into MSIL
Windowsâ PowerShell was built on top of CLR
etc.
I hope you got the idea so far :) MSIL is awesome and weâll definitely talk much more about it in upcoming articles.
And this is where Iâll stop for today. I hope that this article gave you an idea of whatâs coming. And trust me - a LOT MORE interesting stuff is about to come throughout the following weeks! Next time I will be talking about Assemblies, the fundamental unit of deployment for CLR.
Until then!
P.S. If you enjoyed this article, do consider sharing it:
Thanks for reading!
Other articles in this series: