Making software should not be about making the life of the developer as easy as possible, it should be about making things easy, small, and FAST for the user.
Making software should not be about making the life of the developer as easy as possible, it should be about making things easy, small, and FAST for the user.
What are you talking about? It's 1.4MB.
This is the easiest thing in the world to verify:
$ dotnet publish -c Release
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
ConsoleApp -> /tmp/ConsoleApp/bin/Release/net5.0/ConsoleApp.dll
ConsoleApp -> /tmp/ConsoleApp/bin/Release/net5.0/publish/
$ cd /tmp/ConsoleApp/bin/Release/net5.0/publish/
$ du -h
1.4M .
And no, I don't want to hear about any figures for self-contained builds. It's an article about useful packages to help architecture your .NET console app. It's to be read in that context, where the .NET 5 runtime is available.Then what is your point? When talking about the size required for a program to run, you have to weigh all of its dependencies.
For anyone interested, such a binary ends up at least 50MB, if we include the dependencies mentioned in the article in question.
.. if you don't make any use of assembly optimisation/trimming, sure.
$ dotnet publish -c Release
Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored /tmp/ConsoleApp/ConsoleApp.csproj (in 18.97 sec).
ConsoleApp -> /tmp/ConsoleApp/bin/Release/net5.0/linux-x64/ConsoleApp.dll
Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
ConsoleApp -> /tmp/ConsoleApp/bin/Release/net5.0/linux-x64/publish/
$ cd /tmp/ConsoleApp/bin/Release/net5.0/linux-x64/publish/
$ ls
total 29M
> When talking about the size required for a program to run, you have to weigh all of its dependencies.Except the dependencies might not even be relevant depending on which OS you're targeting - and in the context of this article, why is this even interesting? You can make all of the same criticisms of the JVM, or .NET web apps or anything else - do you statically link libc?
Most people just install .NET on their machines. If so, that 1.4mb executable will run just fine.
And to what extreme do you take that line of thought? Should the kernel size be included?
You write:
>And you end up with a console app that is 20-100MB.
Yea, but you can also say
>And you end up with a decent size app that is 20-100MB.
and also you can say
>And you end up with a decent size app that is 2MB
because you already have runtime, because you use .NET apps.
Unless you are only doing Windows tooling, you probably do need to bear that in mind.
EDIT: That said, I do wish that the trimming/tree-shaking systems could do more to get the size and speed of easy-to-code solutions way down.
That depends on the target audience. IME the target audience of console/CLI programs are more likely to care about size. CLI apps tend to cater more to power users. And many users do definitely care about resource usage, and smaller size apps do in fact tend to use less resources.
All users definitely care about performance. A fast app feels nicer. Smaller-sized software tends to be faster. Weird correlation? I think not.
I think what made me defensive was the implication that these CLI libraries can be easily replaced with some small hand-coded solution. This particular library adds color coding, a structured help message based on the configuration, and some building blocks for DI, etc. Getting that stuff right in a hand-coded solution that isn't thousands of lines would take most developers a lot more time and effort.
If that was your takeaway from what I wrote that was definitely not my intention. I do not think that.
I am sure several of these libraries are well-crafted, the developer(s) behind them might be excellent and have cared a great deal about performance and did their best to optimize every function. My point was more: people tend to pull in a lot more functionality/features than they need, and the few things you do need, it is often better to write yourself (you may disagree again).
This will often give you the most optimized solution, and the one with the smallest binary.
In another HN thread, someone mentioned Unity and the size of the binary required just to display a pixel, a square, or whatever their example was--although their example was not an apple-for-apple comparison and not quite fair, the point still stands, that Unity is a general solution, and if your only requirement is drawing a pixel, of course Unity is not the correct solution.
However, I care even more about having apps/tools that help me achieve the desired goals, in an easy, clear, and elegant way.
If having bigger apps means that developers have more time to implement or improve features, and solve bugs, I'm all for it.
Contrast this with a game like Detroit.. It took my system(5700 XT and 3950x) what seemed like nearly 30 minutes to arrive at the menu screen due to having to compile all the shaders and who knows what else. I'm sure there were other considerations there, but still..
You're kidding yourself if you think the average person looks at the size of an app.
FWIW, this is sort of a legacy of .NET's "enterprisey" history. Code size and trimming wasn't really a priority when most .NET code ran server-side or inside enterprises, now it is.
There's been a lot of work happening recently to trim .NET executables and publish them as single files, and it looks like .NET binary sizes will eventually be in the same ballpark as Go: https://blog.kalalau-cantrell.com/2021/01/make-smaller-conso...
Not the lowest rung on the ladder.
So is this type of boilerplate.
I think maybe in 2016? 2018? they were committing a lot to it, probably hoping to make it production ready. Then priorities shifted and they barely advanced and now they moved it into "runtimelab" which doesn't bode well to me.
"Early adopters can experiment with native AOT form factor" is a priority-zero (highest priority) epic for .NET 6: https://github.com/dotnet/runtimelab/issues/248
you do not need CoreRT for trimming. but trimming is already there: https://devblogs.microsoft.com/dotnet/app-trimming-in-net-5/
it's still a long way to go, tough.
In software, the best software is one that was built and works to solve a problem, not necessarily one that is engineered perfectly.
Otherwise slack, chrome, etc... wouldn’t routinely eat up 1GB of ram just to open.
They do, they are well liked.
I know I’m grossly exaggerating, but the fast movement and the lack of ease of use has been one of the primary reasons to see us slowly move toward python and powershell after nearly two decades of C#. Being a windows happy enterprise org, we still make plenty of use of the .Net family and friends of course, but not really for development.
But lets not create this false narrative that somehow .NET has become super complex. Anyone can create a console application with -
dotnet new console -n TestConsoleApp
Python has an argument parser in the standard library
argparse - or close to it :-)
Net tooling used to be horror. Now its good. Speaking as someone who does CI/CD work on it for a long time. You seem to speak as someone who doesn't have .net muscle memory.
Programming is complex, unless you finish with hello world (even hello world is complex in enterprise environments).
As someone who has had to set up MSBuild & other BS for a CI server, I definitely agree with you.
For a dev used to double click Visual Studio, the current setups are more complex.
If 'it works on my computer' is a measure, then pre dot.net core era is as good as it can get.
Even pythons virtual environments take less time to use than .NET.
Sure I actually liked the "double click" thing in Visual Studio, but that had nothing to do with "if it works on my computer", it simply saved bundles of time because we'd publish every project to the same damn IIS instance and not have them all run their independant web-servers with their independant setups.
Hell we still put things behind the same damn IIS instance and it's load balancer and all that, because why wouldn't we? We're not Netflix, we don't need to scale to two billion people. Our max load is 50.000 concurrent users, yet our build load and our deployment pipeline is now so best-practice, SOLIDVOLID, Buzzworded, CONSOLELIEK and complicated might actually work for Netflix with enough iron.
What's worse is that, it's now your job. Not the operations dude who actually specialize in this, no yours, along with keeping up with you know, actual programming.
Being the public sector, we benchmark everything, and the things we don't benchmark we hire E&Y to benchmark, and you know what our most expensive resource has seen the biggest increase of their time going into over the past 30 years? Configuring and maintaining their tooling. Not developing new things that are useful for our actual business, no sir, but working with the tools that allow them to develop things. It's up by 130% compared to 1998.
I'm not sure what you'd call that inside big-tech, but in non-tech, we tend to call that, a waste of resources.
At least we can lower the cost by vendor-lock-in with azure, right?
> I know I’m grossly exaggerating...
I do not even think it is an exaggeration. Even the non-performant Python still feels like a hacker's, get-shit-done language compared to .Net. Anything .Net still feels like slow, enterprise bloat. Even "dotnet build/run" is slow, no matter size of your project.
Seems a bit presumptive to decide the requirements for every console app ever made. Shouldn't it be determined on a case-by-case basis whether a 20mb difference in app size matters?
Also, why exactly does a 20mb app size mean an app is too slow? I'm not really following that line of logic.
The title of the post is "My preferred .NET console stack", not "this is how every console app should be written."
To be honest, I don't think the typical use case for a template like this is to "Make software", it's to solve a problem as quickly and cheaply as possible. Building software to solve these types of problems is 99% about solving the problem and 1% about how well it performs.
I think you’re vastly optimistic about the ratio of ESR-“real-hacker” to “I just work here” developers, as well as the amount an end user cares if the executable is a 100kb vs 100 megs.
Dependencies, dependencies, dependencies = Reuse, modularisation, standardisation of boilerplate
If that would be true people would be using IRC, not Slack or Teams. Users don't care and your statement is completely false.
If you created two Telegram alternatives, that was identical except for performance, would users not choose to use the most performant one?
Statistics like these (I just found at random, but there are many like it available) demonstrates that your average user do in fact care a lot about performance:
https://www.marketingdive.com/news/google-53-of-mobile-users...
If I wrote the perfect chat app tomorrow, I'm talking universally loved by anyone who uses it. I'm not guaranteed to succeed. If someones whole family is on iMessage and they are happy they aren't going to be able to get them to switch. So they couldn't use my app if they wanted too.
Thus they stay with the "inferior" product. Average people aren't interested in the latest greatest. They just want it to work and as long as it does, they don't care about shortcomings that don't affect them. IE app size, speed(as long as its good enough)
I'm being sarcastic :-)