Trying out Native AOT in .NET 7 Preview 7

A few days ago, Microsoft released .NET 7 Preview 7. In this release, they finished most of the work related to Native AOT that was planned for .NET 7. They are planning all the future work for Native AOT here.

I have been following this for a very long time. So why not give it a spin?

Let’s get started.

For .NET 7, Native AOT mainly focuses on console applications. So, let’s create a simple console application:

dotnet new console -n HelloWorld

The Program.cs class contains a simple statement to print “Hello, World!”:

Console.WriteLine("Hello, World!");

Publishing as Single File

Before proceeding to publish using Native AOT, I wanted to know how the same app looks on a single file publish.

So, let’s publish this application as a single file using the .NET CLI command:

dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true --self-contained true

Here if we look at the published output, the size is 64.75 MB. But this includes not just our program but also the runtime because of the use of --self-contained true flag:

Published output for PublishSingleFile + SelfContaied options
PublishSingleFile + SelfContaied

Let’s add one more switch PublishTrimmed which will remove all the unnecessary code in our application (including all the Base Class Libraries(BCL) and package references):

dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true

Now, the PublishTrimmed option significantly reduces the size to 11.30 MB!

Published output for PublishSingleFile + PublishTrimmed + SelfContaied options
PublishSingleFile + PublishTrimmed + SelfContaied

Single file publish includes all the assemblies in a single file. Therefore, it makes the app distribution easier.

But the published output contains Intermediate Language (IL). JIT compiler needs to convert it to native code at runtime. This works great for most scenarios. But it’s not ideal for resource-constrained environments and where the application startup time is crucial.

Let’s add one more switch PublishReadyToRun. R2R improves the startup performance by compiling the code on the startup path directly to native code. R2R places the native code alongside the IL. Hence, there is a slight increase in the published application size (14.76 MB):

Published output for PublishSingleFile + PublishTrimmed + PublishReadyToRun + SelfContaied options
PublishSingleFile + PublishTrimmed + PublishReadyToRun + SelfContaied

Publishing as Native AOT

Unlike R2R, Native AOT complies entire application to native code just like C++, Go, Rust, and similar others.

Now, let’s go ahead and publish the same console application as Native AOT using the PublishAot MSBuild property:

dotnet publish -c Release -r win-x64 -p:PublishAot=true

Alternatively, we can specify the property in .csproj file as well:

<PropertyGroup>
    <PublishAot>true</PublishAot>
</PropertyGroup>

Important

Before going ahead, we need to install Desktop Development for C++ workload through Visual Studio Installer. Otherwise, an error will be thrown:

C:\Program Files\dotnet\sdk\7.0.100-preview.7.22377.5\Sdks\Microsoft.DotNet.ILCompiler\build\Microsoft.NETCore.Native.Windows.targets(115,5): error : Platform linker not found. To fix this problem, download and install Visual Studio 2022 from http://visualstudio.com. Make sure to install the Desktop Development for C++ workload. For ARM64 development also install C++ ARM64 build tools. [D:\HandsOn\NativeAOT\HelloWorld\HelloWorld.csproj]

After running the command, with obj and bin folders removed, it took me under 9 seconds to produce the native binary. But later, it took me under 3 seconds:

Published output for PublishAot option
PublishAot

Impressive! the application size is only 3.65 MB! The published output is purely native. No Intermediate Language (IL) is present. But why 3.65 MB for a simple “Hello, World!” application you might ask? Well, these results are for good defaults. But, we can further reduce this size. Please look for optimizations here.

What about something more than just a “Hello, World!” project? Well, here’s a tweet from @MStrehovsky:

We know this is just the beginning and there’s more to come. I just can’t wait to see more real-world projects making use of Native AOT and show us their results. Are you building a cool project using Native AOT? Please let everyone know in the comments!

Also, let’s take a moment to appreciate all the people who were involved in getting this feature out for all of us!

If you wish to read more on publishing using Native AOT, Microsoft has detailed documentation here.

Happy Coding 🙂

Leave a Comment

Your email address will not be published.