It’s been a hot minute since I wrote any C# (pre .NET Core). I kicked the tires yesterday. I have to say, documentation is all over the map, and the old DI / enterprisey boilerplate is still alive and well. Coming from a Node + TypeScript, Ruby, and Go world, C# still feels like a lot of ceremony. So, I gave F# a spin again. It’s always had a special place in my heart. But while the language is fantastic, the tooling (on OS X) and documentation made it difficult to get off the ground.
So, what’s the best-organized resource for getting up to speed on .NET these days?
I’m a Dev doing mostly C# and JS. I’ve heard some of the complaints on HN mentioning DI and really don’t get it. I honestly feel like it makes my code cleaner and more testable. For example, I don’t have to care where my IFooService comes from or how best to instantiate and dispose, I just request one in the constructor. For a framework to be flexible, you need _some_ plugin capability. Asp.net seems to do pretty good at giving you nice defaults but letting you swap out with DI. All my dependencies are laid out nicely in one place (Startup.cs) and then used throughout. DI gives you that and I’m glad that it’s baked in now as opposed to having to pick a 3rd party. Maybe I’m biased, though. Help me understand why NOT to use DI? Is it just moving people’s cheese or are there other reasons?
Regards ceremony and DI: I think the templates are more Ruby on Rails style while the framework can be trimmed down to nodejs + express simplicity. This sample here is node+express like equivalent (thanks to C# 9.0 top level statements, there is not even a Program class and a Main entry point)
WebHost.CreateDefaultBuilder().Configure(app =>
{
app.UseRouting();
app.UseEndpoints(e =>
{
e.MapGet("/", c => c.Response.WriteAsync("Hello world!"));
e.MapGet("hello/{name}", c => c.Response.WriteAsync($"Hello, {c.Request.RouteValues["name"]}"));
});
}).Build().Run();
I also stumble over that once in a while but I have no hard feeling on it.
I recently ran through the entire ecosystem thinking that there must be something akin to Sinatra (micro web framework) in .Net. Nope. Every single thing is built on top of ASP .net.
I did find a WIP library where they are trying to go for a low ceremony framework https://github.com/featherhttp/framework, but even that is built on top of ASP .net
For me the worst bit about .Net is their treatment of F#. IMO, it is one of the most practical and usable functional languages out there. But none of the official docs have anything on F# at all.
Here is an example doc; see if you can find any code example for F#.
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor...
Its always C#. And I have 0 interest in that kitchen sink language.
Between ASP.Net and C# being the entire world for .Net, I have really not much interest in using it for anything. There are plentiful of interesting languages and ecosystems that I can use for my small time projects.
The .Net Core documentation is indeed a dumpster fire. As a longtime C# guy I can't even find the up-to-date "blessed" way to do things with ASP.NET anymore. They change it every version it seems. The DI/IoC stuff is definitely too pervasive, particularly in an ASP.NET context.
That said, the new C# language features really do reduce boilerplate when used judiciously - multiple return is now available, "expression-bodied properties", improved template strings etc. Lots of good stuff that is hard to find good documentation for :)
I don't really feel like there is that much more boilerplate with C# than there is with TypeScript (although I do like TypeScripts's ctor shorthand that creates members for you from ctor params).
C# 9 also brings top-level programs, which essentially eliminate all ceremony for the entrypoint[0] - an app can now be as simple as:
I think it's a result of MicroSoft shifting to the mindset that performance is a feature.
I have been a .Net developer for about 15 years and remember when it was a violation of terms of service to publish .Net performance measurements. Especially performance comparison against Java was something that would get you on Microsoft's bad side real quick.
So it's really I think the difference between performance being a secret, and it being on the front page and Microsoft throwing significant developer resources into it.
Not sure how .NET holds up against Java but for the last decade or so its been common knowledge that .NET on Windows was way way faster than most of the interpreted web frameworks out there (PHP, Ruby, etc etc). Compiled vs interpreted, its pretty obvious. This 2013 post about Stackoverflow being served by just two IIS servers is fairly legendary: https://nickcraver.com/blog/2013/11/22/what-it-takes-to-run-...
My point being, I thought .NETs performance was pretty well regarded already fwiw.
Go is faster than .NET and the code is shorter. On average, results may vary.
I looked at the benchmarks.
In cases where .NET is faster it's because the C# version is optimized using unsafe code and x86-specific (i.e. non-portable) AVX2 intrinsics to do the math.
Go version is written in straight-forward way. I think all Go programs are shorter than their C# version.
There has long been this perception that Go is a low level language. In the sense that it isn't rich in complicated features, this is true. But it is a garbage collected language, it manages it's own stack which is less low level than C#, and it doesn't provide any low level control over memory/instructions that C# doesn't, less in fact. And the cost to interop with C is higher with Go than with C#.
I think the fact that Go compiles to native executables as the default, just gives the impression that it is "low level". That and the lack of features I suppose.
I say all of this as someone who loves Go as a language by the way. C# could use some simplification!
Great, but I would rather see a perf comparison of .NET 5/Core vs .NET 4.7 because .NET Core was a new technology that may have traded performance for features in its first versions. Similar to how JDK 14 beats JDK9..13 but still in many cases is behind JDK8.
.NET Framework had a outdated Web stack (System.Web over IIS). In 2014 it was 13 years old with little chance to improve anything without breaking someone. That was the whole reason why .NET Core became a thing.
.NET Core in Version 1.0 cheated then by just taking the network layer of node.js called libuv and linked it up (C -> .NET) . In Version 2.x they wrote and independent socket based networking layer straight in C# which outperformed libuv significantly. In Version 3.x they switched over to use new low level runtime primitives (e.g. Span<T>) which could never have been delivered in the .NET Framework (no breaking changes!). Now in .NET 5 more runtime improvements were added.
I think that on the contrary, .net core already had much better performance but less support for some desktop windows stuff, and .net 5 actually added most of the remaining features back.
I don't know any definite benchmarks, but anecdote, the unit tests of a bigger library[1] I am writing run in 10s on net5 vs 12s on dotnet 3.1 (core) vs 17s on .net48 (framework), on the same machine with warm caches, of course. That's a sizable difference. YMMV
[1] not web stuff, "plain" C# essentially. It has some compute-bound things like encryption and compression and some fancy tree structures, uses a lot of linq in certain parts.
Still slower than Dapper though? I like Dapper and we use it where I currently work, but it enables people to maintain their bad practices brought over from raw SQL. I would like to see EF Core narrow that gap in performance a bit
a lot of the standard library has been updated to use simd where possible, there are new features for dealing with memory that let you get c level performance for more things, this has been leveraged to move some things in the standard lib from c to pure c# which plays nicer with the GC for big wins. the jit has also been improving what things can be devirtualized, and linq has had some performance tweaks
I find it amazing that there are so many incorrect criticisms of dotnet being made in this thread. It’s honestly as though a number of people with barely any experience with the platform have decided they’re experts and come in to tell everyone else how terrible it is. I shudder to think how many other threads about technologies I know less about also suffer from this affliction.
It’s a shame indeed and I hope this site will improve its ability to boost comments with value to add.
There are some interesting and insightful comments even in those under this article though. I find hiding the entire tree once I see a comment that’s just there for the sake of being negative makes it easier to find the valuable ones.
I remember trying it out (on Linux, that is), and really liked the concept, but it was painfully slow, so it was no fun for me. Like, waiting 3-5 seconds in the REPL for a single line to compile and execute.
It will become somewhat faster as soon as it upgrades due to the improvements in the class library. However, I doubt that PowerShell performance relies significantly on .NET itself. It is PowerShell who needs to be implemented efficiently.
PowerShell has never been that slow for me, if you wouldn’t mind you should probably file a bug about that if you’re still experiencing it. I have found it to start slowly sometimes but once it’s hot I have no performance issues.
Haven't noticed any improvement in my project, but there is just arrays and 4 arithmetic operations. I guess the improvements are in more complex library functions like regex.
In general you should always be able to get the same performance, but you will have to use less idiomatic F#. Then again, the highest performing C# isn't idiomatic C# either.
I sometimes suspect the whole raison d'être of dot.NET, docker, kubernetes etc, is to render programming into such an esoteric art, that the hoi polloi can be excluded.
--
This is a minor corner of .NET 5 but I'm bummed that .NET's Blazor (WebAssembly) has no way to interact with the HTML Canvas from C#, so you have to write JS interop code, so its quite slow (that is, C# WebAssembly with Canvas is slower than just writing JS).
My hope was that by the time .NET 5 was out of preview, we would have seen something for this so people could write C# for Canvas in WebAssembly. Alas, not yet!
from the perspective of a rust, c, c++ developer it was a bit slow as all GC based languages are. Before this .net core was already arguably the gc language with the highest performance ceiling.
this can of course depend on workload and whether you care about startup time or throughput vs tail latency etc, but on the whole it tended to allow you beat out java, go and other competitors most of the time.
with AOT being a standard option now, getting quick startup time is easier too, along with the other improvements
I'm not sure where on earth you have got this notion from; the .NET Core team have been performance focused for a long time now, and blog posts from the .NET team detailing perf improvements have been posted on HN multiple times.
You even have hardware intrinsics available to play with, and for performance-sensitive libraries such as hashing algorithms, it's typical for performance to come within spitting difference of RAM speed.
This somehow reminds me of an old gamedev trick when at the start of the development cycle you'd declare a huge static array somewhere in the code to "reserve" some memory. You'd then "rediscover" and reclaim it a year later when the game needs to ship but no longer can fit in a memory.
That is, any sort of astonishing improvements is often a sign of the original version being crappy, so it's also a red flag even if it's ultimately the good news.
[+] [-] christophilus|5 years ago|reply
So, what’s the best-organized resource for getting up to speed on .NET these days?
[+] [-] shireboy|5 years ago|reply
[+] [-] oaiey|5 years ago|reply
[+] [-] rishav_sharan|5 years ago|reply
I recently ran through the entire ecosystem thinking that there must be something akin to Sinatra (micro web framework) in .Net. Nope. Every single thing is built on top of ASP .net.
I did find a WIP library where they are trying to go for a low ceremony framework https://github.com/featherhttp/framework, but even that is built on top of ASP .net
For me the worst bit about .Net is their treatment of F#. IMO, it is one of the most practical and usable functional languages out there. But none of the official docs have anything on F# at all. Here is an example doc; see if you can find any code example for F#. https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor...
Its always C#. And I have 0 interest in that kitchen sink language.
Between ASP.Net and C# being the entire world for .Net, I have really not much interest in using it for anything. There are plentiful of interesting languages and ecosystems that I can use for my small time projects.
[+] [-] eric_b|5 years ago|reply
That said, the new C# language features really do reduce boilerplate when used judiciously - multiple return is now available, "expression-bodied properties", improved template strings etc. Lots of good stuff that is hard to find good documentation for :)
[+] [-] GordonS|5 years ago|reply
C# 9 also brings top-level programs, which essentially eliminate all ceremony for the entrypoint[0] - an app can now be as simple as:
[0] https://dotnetcoretutorials.com/2020/08/30/top-level-program...[+] [-] apalmer|5 years ago|reply
I have been a .Net developer for about 15 years and remember when it was a violation of terms of service to publish .Net performance measurements. Especially performance comparison against Java was something that would get you on Microsoft's bad side real quick.
So it's really I think the difference between performance being a secret, and it being on the front page and Microsoft throwing significant developer resources into it.
[+] [-] codeulike|5 years ago|reply
My point being, I thought .NETs performance was pretty well regarded already fwiw.
edit: here you go, ranking of web frameworks: https://www.techempower.com/benchmarks/#section=data-r19&hw=...
ASP.NET Core 3.1 holds up pretty well, only beaten by C++, Rust, and a Java/Kotlin Framework called Jooby
[+] [-] pjmorris|5 years ago|reply
[+] [-] hollabolla2|5 years ago|reply
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
But unlike GO, you will need to write 50x less lines of code to achieve the same result.
[+] [-] kjksf|5 years ago|reply
I looked at the benchmarks.
In cases where .NET is faster it's because the C# version is optimized using unsafe code and x86-specific (i.e. non-portable) AVX2 intrinsics to do the math.
Go version is written in straight-forward way. I think all Go programs are shorter than their C# version.
Compare mandelbrot benchmark:
* https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
* https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Those are not fair comparisons and therefore don't paint the correct picture of relative performance.
[+] [-] gameswithgo|5 years ago|reply
I think the fact that Go compiles to native executables as the default, just gives the impression that it is "low level". That and the lack of features I suppose.
I say all of this as someone who loves Go as a language by the way. C# could use some simplification!
[+] [-] smarx007|5 years ago|reply
[+] [-] oaiey|5 years ago|reply
.NET Core in Version 1.0 cheated then by just taking the network layer of node.js called libuv and linked it up (C -> .NET) . In Version 2.x they wrote and independent socket based networking layer straight in C# which outperformed libuv significantly. In Version 3.x they switched over to use new low level runtime primitives (e.g. Span<T>) which could never have been delivered in the .NET Framework (no breaking changes!). Now in .NET 5 more runtime improvements were added.
[+] [-] resoluteteeth|5 years ago|reply
[+] [-] runevault|5 years ago|reply
[+] [-] rndgermandude|5 years ago|reply
[1] not web stuff, "plain" C# essentially. It has some compute-bound things like encryption and compression and some fancy tree structures, uses a lot of linq in certain parts.
[+] [-] GordonS|5 years ago|reply
I haven't come across a package that isn't available for .NET Core in at least a couple of years, I think.
[+] [-] gameswithgo|5 years ago|reply
[+] [-] skrowl|5 years ago|reply
[+] [-] y-c-o-m-b|5 years ago|reply
[+] [-] wffurr|5 years ago|reply
[+] [-] Avalaxy|5 years ago|reply
[+] [-] gameswithgo|5 years ago|reply
[+] [-] RobCrusoe|5 years ago|reply
[+] [-] tokamak-teapot|5 years ago|reply
There are some interesting and insightful comments even in those under this article though. I find hiding the entire tree once I see a comment that’s just there for the sake of being negative makes it easier to find the valuable ones.
[+] [-] perlgeek|5 years ago|reply
I remember trying it out (on Linux, that is), and really liked the concept, but it was painfully slow, so it was no fun for me. Like, waiting 3-5 seconds in the REPL for a single line to compile and execute.
[+] [-] oaiey|5 years ago|reply
[+] [-] jolux|5 years ago|reply
[+] [-] majkinetor|5 years ago|reply
Kill the bitch and you will have normal times.
[+] [-] BMSmnqXAE4yfe1|5 years ago|reply
[+] [-] fulafel|5 years ago|reply
[+] [-] phillipcarter|5 years ago|reply
[+] [-] igouy|5 years ago|reply
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
[+] [-] gameswithgo|5 years ago|reply
[+] [-] Stierlitz|5 years ago|reply
DI == Dependency Injection
[+] [-] simonsarris|5 years ago|reply
My hope was that by the time .NET 5 was out of preview, we would have seen something for this so people could write C# for Canvas in WebAssembly. Alas, not yet!
[+] [-] ksec|5 years ago|reply
Is it basically LiveView on Elixir?
[+] [-] ncmncm|5 years ago|reply
[+] [-] unnouinceput|5 years ago|reply
Personal wish for author (Alex Yakunin) - now compare it with rest (Java mainly).
[+] [-] alexyakunin|5 years ago|reply
As for me, I wrote https://medium.com/servicetitan-engineering/go-vs-c-part-3-c... that compares C# and Go, and conceptually nothing changed a lot from the moment this was written.
IMO Go is the only viable competitor to .NET nowadays. Java is holding there solely because of Android - performance-wise it's so far behind...
[+] [-] gameswithgo|5 years ago|reply
[+] [-] greg7mdp|5 years ago|reply
[+] [-] gameswithgo|5 years ago|reply
this can of course depend on workload and whether you care about startup time or throughput vs tail latency etc, but on the whole it tended to allow you beat out java, go and other competitors most of the time.
with AOT being a standard option now, getting quick startup time is easier too, along with the other improvements
[+] [-] robinei|5 years ago|reply
[+] [-] squid_demon|5 years ago|reply
[+] [-] GordonS|5 years ago|reply
You even have hardware intrinsics available to play with, and for performance-sensitive libraries such as hashing algorithms, it's typical for performance to come within spitting difference of RAM speed.
[+] [-] gameswithgo|5 years ago|reply
i feel like a lot of people’s ideas about c# performance are from before .net framework 4 which was years and years ago
[+] [-] renanoliveira0|5 years ago|reply
[+] [-] huhtenberg|5 years ago|reply
That is, any sort of astonishing improvements is often a sign of the original version being crappy, so it's also a red flag even if it's ultimately the good news.