💾 Archived View for gemi.dev › gemlog › 2023-01-11-dotnet-framework.gmi captured on 2024-05-10 at 11:18:43. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
2023-01-11 | #programming | @Acidus
I primarily write code in C#, and all the CGIs here like Gemipedia, NewWaffle are written in C# on a Mac. My capsule runs on a simple Linux VPS. Luckily .NET code is cross platform. I use "make" to build the CGI programs and rsync them to my capsule.
Without getting to much into the specifics of .NET and building/publishing apps, there are 2 broad ways to publish an app
When building my first CGI, I used "self-contained" approach to reduce the number of variables like the location of the .NET runtime, versions, permissions, PATH variables, etc. My understanding was, my executables would be bigger because each folder contained my code plus all the Microsoft code of the runtime. It took up more space, but I largely didn't care.
As I added more CGIs I just kept copy+pasting the same Makefile lines over and over again, and didn't really think much of it.
Except now I have 6 CGIs (plus some programs for offline tasks) and sending 6 different copies of the .NET runtime (or at least the parts that each CGI used) over and over seemed silly. rsync is fast, but sending 6x more data than you need to is silly. So I went ahead and setup .NET on my Linux VPS and moved to using framework-dependent builds
For other .NET developers out there, all I'm doing is:
dotnet publish -c Release -r linux-x64 --self-contained false $(codeDir)/NewsWaffle/NewsWaffle.Cgi/NewsWaffle.Cgi.csproj
My rsyncs were faster, but I also noticed about the executables themselves ran faster. Using "time ./NewsWaffle.Cgi" I see a 150ms difference on my VPS between executing the self-contained and framework-dependent approaches. This code path simply prints the main static page of NewsWaffle, without any serious CPU or any network requests. I see about 150ms difference
I don't have a strong answer for the difference. I'm not Ahead-of-time JITing. I suspect it has to do with the overhead of opening the numerous and fragmented .NET runtime libraries that come with the self-contained app, but even then I would suspect that that disk access would be cached in RAM and not significantly different than the shared .NET runtime libraries. I'm not entirely sure.
Regardless of the source, it goes to show that: