For my next trick I'm going to build a 64 MB self-contained game in C# and then shrink it to 1936 bytes in 10 steps. Read all about it in my latest article:
New version of bflat, my take on C# with Go-like tooling is out. New in the 7.0.1 release: build C# apps that run on bare metal hardware without an OS.
7/7 Turns out the object files produced by the CoreRT ahead of time compiler from 2020 can still be linked with the linker that shipped with Visual C++ 2.0 in 1994. So it's C# compiler -> CoreRT Compiler -> Linker -> Success.
@web3isgreat
No no no, if you make a NFT and the server hosting the jpeg burns down you still own the NFT. The token still exists and is in limited supply just as before! Nothing has changed! What NFT is doing to the concept of asset, few understand!
Everything you wanted to know about making C# apps that run on bare metal, but were afraid to ask: . A complete EFI boot application in a single .cs file.
I took a chapter from Go and applied it to the tools we use to build C#. The result is a C# crosscompiler producing small/selfcontained/native executables for Linux and Windows. Try it out now:
Made a bare metal bootable maze "game" in C# as a demo of what's possible with bflat's zerolib. Anyone interested in reading a write-up of how I did it? Source here:
Got
@stevensanderson
's WebWindow Blazor sample running with CoreRT. 4x smaller self-contained deployment than CoreCLR. 37% less RAM. WebWindow already beats Electron in size and memory with CoreCLR, but CoreRT wipes the floor with Electron
After reading
@fabynou
's article about the DOOM fire effect, I decided to implement the effect in C# and get it running on Windows NT 3.51. Read all about it here:
CoreRT now makes it possible to build self-contained C# apps that are smaller than 1 MB (without much hacking). It's a journey and we're not at the end of it. This pull request has some details (and instructions, if you dare to try!):
Needed a UTF-8 string literal in C# today (again...). I was about to write another unintelligible `new byte[] { }`. Then I realized source generators could be used for that... and a search for "UTF-8 C# source generator" didn't disappoint. Cool project!
Today marks my 10 years at Microsoft. 2 years in Windows and 8 years in .NET. I actually got rejected the first time I applied for an internship in 2007 but I didn't take no as the answer.
1/N One of my favorite optimizations in the upcoming .NET 7 Native AOT is static data preinitialization. This program prints a circle to the screen. Would you believe me if I said there is no code to compute the circle bytes in the NativeAOT'd executable file of this program?👇🧵
Size of fully self-contained natively-compiled Hello World over the course of .NET 7 previews. This is release build with everything left on default settings, producing a standalone EXE you can just copy to a machine and run. Hello World now under 3 MB by default with PublishAot.
.NET Core 3 introduced IL Linker tool to help remove unused code and build smaller apps. Linker operated conservatively because with reflection, it's hard to say what's used. In .NET 5 we'll enable more aggressive removal while keeping apps working.
bflat, my take on C# with Go-like tooling, is now open source. New builds coming as soon as I write the Github actions to create them. You can build it from source in the meantime:
6/7 Glad you asked. In 1992 Microsoft shipped an addition to Windows 3.11 called Win32s. This let people run *some* 32-bit apps on the otherwise 16-bit system. Not all Win32 APIs were available, but surprisingly many apps still worked with it. Like Office 95.
C# is attacking the
#1
spot in the TechEmpower Plaintext benchmark. C++ is confirming its "fast, but hard to get right" status (judging by the "Errors" column).
Last week, CoreRT received a big contribution towards running on all 3 major game consoles. We can't host the full solution due to NDAs, but a skilled dev with the NDA console SDK shouldn't have a too difficult time now.
Size of fully self-contained natively-compiled Hello World over the course of .NET 7 previews. This is release build with everything left on default settings, producing a standalone EXE you can just copy to a machine and run. Hello World now under 3 MB by default with PublishAot.
Came back to this out of sheer curiosity. The reason why the Windows NT 3.1 Minesweeper shows up in B&W on Windows 11 is GetDeviceCaps(NUMCOLORS) returning -1 because the number of colors don't fit in 32 bits. Left: original. Right: restored to full glory with a memory patch.
@davidwengier
@beeradmoore
Wondered if anyone else would notice! I played with the Compatibility tab of the EXE properties to see if any of the quirks would fix it but none of them did. Winmine.exe is 45 kB - shouldn't take too long to debug, but got other things to do. Color on old things fades!
Thank you for the 1000 GitHub stars - I hope to bring systems programming in C# forward this year! We already have a great language (C#: now with function pointers!) and AOT compiler (ILC: now with "constexpr"!). We now need a great runtime library.
I've released v8.0 of bflat - my take on C# with a native-first compilation model. If you're on Windows you can grab it with `winget install bflat`. Linux version in the repo releases tab.
Work in progress to add support for covariant return types to the .NET runtime. Soon we'll be able to override a virtual method returning `object` with a method returning `string`. Because of how array variance works, weird things might be possible in IL.
I've pushed out a new version of the bflat C# compiler/runtime. The latest addition is the Sokol libraries that make it possible to build 100% standalone GFX/audio apps in C# with app sizes starting at around 720 kB, uncompressed. Get it from
A new version of bflat, my C# compiler that builds native and self-contained binaries, is out. I bumped the version to 7.0 so that one doesn't have to think which .NET version it's based on and dropped the "pre-release" tag. Consider bflat "done".
Build fully self-contained .NET 7 command line apps starting at ~800 kB with PublishAot and PublishAotCompressed! The new version of PublishAotCompressed bumps the UPX compressor to version 4.0.1 that shipped a couple days ago. Grab it from NuGet:
For the followers of mine who still use 💾, I have good news: we're on track to fit a fully self-contained, AOT-compiled Hello World in C# built with default settings on a single floppy.
If you are doing file I/O in .NET and your access patterns involve a lot of seeking and reading from random spots, try switching from FileStream to MemoryMappedViewStream 🚀
I've upgraded my "Systems programming with C#" samples to .NET 6. Build scripts are now replaced with csproj. One can also build for Linux (and maybe Mac, but I didn't test). Feels good closing pretty much all open issues in the repo.
Life hack: uninstalling the Notepad app in Windows 11 (with Add/Remove programs) makes things fall back to the old Notepad that launches instantly and consumes 20x less memory.
Talking about Hello World binary size always wakes up nostalgics ("Hello world on Amiga is 128 bytes") and people with misconceptions ("it's a couple kilobytes with C"). Made a repo to put sizes of Hello Worlds under scrutiny and bring facts to the table
The best part of this? `PublishTrimmed` now actually means "publish the whole app trimmed". Here's size numbers for a sample app that uses ImageSharp to save a PNG file before and after Preview 7. The NativeAOT numbers are especially nice.
Announcing .NET 7 Preview 7 ‼️
It includes improvements to:
✅ System.LINQ
✅ Unix file permissions
✅ low-level structs
✅ p/Invoke source generation
✅ code generation
✅ websockets
See what else is new, give it a try, and tell us what you think:
Reflection.Emitted property accessor is about 35 times faster than PropertyInfo.GetValue, but in the time spent Emitting and JITting a single fast accessor you can call PropertyInfo.Invoke more than a thousand times. Optimize for what matters the most to you.
#NowYouKnow
I've released a new version of my bflat compiler. This is a release candidate catching up to .NET 8. Apparently GitHub is having some issue with the daylight savings time and this release comes from the future. Grab it while it's still hot:
1/N If you're using PublishAot and want the shrink your app size by extra 60-70%, add a reference to this package and `dotnet publish` with `PublishAot=true` as usual:
pdfmerge is a tool in C# to merge PDF files I wrote in a couple minutes with the help of GPT-4. 2 MB in size and will run on a clean OS install. Repo also shows automating releases with GitHub actions. Very little effort to build useful CLI tools with C#!
Just realized that as a principal software engineer at Microsoft I get the *same* salary that I was getting 11 years ago as a Software Engineer 1 (at Microsoft). My trick? Moved from Redmond to Europe. With the EUR/USD exchange rate now, my annual base pay in USD reached 5 digits
David always comes up with the appropriate memes. The NativeAOT experiment will be moving from the dotnet/runtimelab repo into the dotnet/runtime repo!
5/5 Voila - 2,121 bytes! It's so small that this 100% selfcontained C# game binary now fits in a QR code (base64 encoded). You need a good QR code reader though because this is an insane QR code. But still...
New version of Sizoscope, my tool to inspect size of .NET native AOT binaries is out. If you're on .NET 9, the tool will now show you "frozen objects", a frozen part of the GC heap that the compiler generated ahead of time. They're the result of executing your code ahead of time.
1/5 "Ugly side of default interface methods" time. Interface with two methods, one with a default implementation. What will the following program print?
New version of bflat, my take on a selfcontained C# to native code compiler is out. This release adds an extra base class library that is an extreme subset of .NET. One can't build much with it, but one _can_ build a C# snake game into ~10 kB of selfcontained native code with it
bflat C# compiler 0.0.5 is out. It's now tracking the .NET 7.0 stabilization branch. Natively crosscompile your C# code from Linux to Windows and vice versa. Just a 70 MB download, no other SDKs or dotnet needed.
Linux devs: Windows has a ridiculous number of APIs - it takes forever to master that. Also Linux devs: why would you build a strongly typed API for stuff that people can parse out of text files in /proc/self?
GitHub should have a "Merge with fireworks" option so that I can get a closure after spending a day in a debugger and only have a trivial one-liner fix to show for it.
First world problem: A .NET Native AOT gRPC app benchmark shows a significant improvement, and no one can figure out why.
Time to first response dropped from about 12ms to 5ms 🚀
For comparison, the time to first response without AOT is about 125ms 🐌
With .NET 8 Preview 5 out today, this finally fully works including root cause analysis. (No need to download .NET 8 daily builds to take full advantage of this tool.)
1/2 Found out the VC++ compiler can compile C into .NET IL with the `/clr` switch if you pass an extra undocumented switch to allow C. Contrary to popular belief, C _is not_ a subset of C++ and most C code would not compile as C++ (or Managed C++ or C++/CLI).
1/2 When you publish your app as Native AOT in .NET 7, you give up the ability to load new assemblies at runtime. Some say it's a limitation - I say it's an opportunity.
Since in 2020 the only kind of software that still cares about the size of the EXE is malware, this is the sad reality of building tiny < 10 kB programs. IT'S A 5 KB SNAKE GAME I WROTE IN C#. IT'S NOT GOING TO ATTACK THE POWER GRID IN YOUR COUNTRY.
The database engine at the core of many Windows components is now open source under MIT license! I got to work with it many years ago when I was working on the Windows component that aggregates app battery usage history. The component uses this engine to store the data.
New version of my PublishAotCompressed package is out. It updates UPX to latest version and adds property to enable LZMA compression. A fully self-contained natively compiled C# Hello World, including GC and everything can be as small as ~440 kB.
Not so long ago Cesium, a C17 compiler targeting .NET platform I develop, was able to compile a fully standard "Hello, world" program for the first time.
Today, I've prepared some contributor documentation and laid out the further plans. Go, check it out!
1/2 Thought about UWP development today and boy am I glad "developer license" did not catch on. Having to acquire a license to develop on general-purpose computers is a crazy idea that Apple pioneered and is still trying to push on today. It must not be normalized.
I've released a new version of bflat, my C#-to-native compiler driver based on .NET 7. This release extends platform support (ARM64, including Android) and adds more options to make the produced selfcontained programs smaller. Try now:
Part of the CoreRT AOT compiler moved to the CoreCLR repo to lay the foundation of the "next crossgen". It won't be full AOT, but some of the advancements we made in the CoreRT repo are becoming part of a shipping product again to build better ReadyToRun:
Got the HelloWorld and DynamicLibrary bflat samples running on my Android phone. New version of the bflat compiler coming soon! Publishing C# libs & command line apps is going to be as easy as 'bflat build --os linux --libc bionic --arch arm64', no dotnet or Android SDKs needed.
I personally hope this also means we are going to stop relying on the JIT eating electricity and creating heat to recompile 𝘁𝗵𝗲 𝗲𝘅𝗮𝗰𝘁 𝘀𝗮𝗺𝗲 𝗰𝗼𝗱𝗲 billions and billions of times in hundreds of thousands of data centers and billions of end user devices every day.
Today Microsoft announced an ambitious goal and a detailed plan to become carbon negative by 2030, remove our historical carbon emissions by 2050, and launch a $1B climate innovation fund.