.NET Myths Dispelled

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • SaaSHub - Software Alternatives and Reviews
  • .NET Runtime

    .NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.

  • > It is irrelevant that the benchmark is written in Oberon.

    It is not irrelevant from my perspective. It might be mostly irrelevant if Oberon, as you say, "fairly directly" translates to CRL/IL, that is, there is no need to introduce any (inefficient) glue constructs to support Oberon features. I didn't/do not know this, but if you say this to be the case now, good, that answers my doubts in that regard.

    However, this still does not speak to how good the codegen of your Oberon-to-CLR/IL compiler is. Yes, the mono or CoreCLR JIT will apply further optimizations, but in a significant part it relies on the quality of the codegen of the IL it gets passed to do so.

    >The fact that Mono is only a factor of two behind is pretty good.

    According to your benchmarks. I'd still be a lot more interested in how well the CoreCRL would fare when handed CLR/IL generated from idiomatic C# or F# by the dotnet (Roslyn) compiler. On recent hardware. Or at least a recent hardware architecture.

    Right now, it seems to me you're doing something analogous to compiling C with tcc and then making general performance statements about C performance based on tcc generated machine code. Even your own mono-3 and mono-5 results differ, so choice of runtime is clearly a factor.

    >It is irrelevant that C# is the most commonly used language on .NET; it is by definition and design a "common language infrastructure", and the article comments on .NET in general (and makes claims at least as adventurous as yours, the ones discussed here also without supporting evidence).

    It is not irrelevant. The claims unsupported by any evidence are yours by the way. You made statements about performance, and all you presented is what I consider at best highly questionable methodology. If you make such claims, and try to back them up by "data", you'll have to demonstrate that your Oberon+-benchmark-code-compiled-to-CLR/IR-as-run-on-old-mono-on-outdated-hardware benchmark methodology is indeed something that can be used to make such claims about ".NET" in a sound manner. As I said, I doubt that, and that's all I did, express doubts about your methodology, and why I have these doubts.

    > Regarding your nonsensical claims about Span<> and stackalloc, I recommend that you take a look at ECMA-335 and its development over time (and at the generated code).

    I have been following standard library and CLR/IR development, and Rosyln compiler development, and therefore know that my statements are not nonsensical. E.g. here[0] is the dotnet "Augments" document that lists, aside from many clarifications, outright additions not present in the latest ECMA-335 spec. See e.g. the changes/additions regarding Byref-like types, which in practice allow for all kinds of optimizations, a lot of them implemented in CoreCLR 5 or 6, but of course only enabled if the compiler's codegen emits these new byref-like type variants.

    Furthermore, a lot of the optimizations that current-generation to-CLR/IL compilers and runtimes/JITs perform do not rely on changes to ECMA-335 at all. E.g. as I mentioned above, your mono-3 runs the CLR/IL your compiler generated significantly faster than your mono-5.

    >Also your assertion about the relevance of the HDD and the other mentioned hardware aspects makes me doubt whether you have any idea at all about what you are writing here

    You're running on a somewhat memory-constrained old machine, so even if you try to run your benchmarks "hot", i.e. have everything required loaded into OS-level caches before the timing starts, I wouldn't be convinced that this is necessarily the case (disk cache pages might have been evicted, and pages in general might have been swapped out and need swapping back in again during a run, and if that happens the HDD performance would play a major role). Additionally, laptops (with relatively early versions SpeedStep-capable CPUs, as your is) are particularly susceptible to additional issues that might adversely affect the reliability of benchmark results, e.g. thermal throttling.

    If any of this happens, it might be (but is not necessarily) detectable in e.g. stddev (your benchmarks pdf lacks any mention of stddev, so I cannot know).

    I remember trying to benchmark something compute-heavy on my HP Elitebook 8440p[2] back in the day, and gave up after I couldn't get the thing to produce any sane results for different runs of the same code.

    The choice of your hardware might as well matter and create vastly different proportional results between the different runtimes you test when the same benchmarks are run on different hardware, even if there aren't any of the problems I described.

    As I wrote, your choice of hardware and software (and my anecdote) does not necessarily invalidate your results, but it might render your results rather meaningless for other, more commonly used current generation hardware. And that's something to be aware of.

    >so why should people take the effort of making measurements and publishing data?

    Sorry, but the effort you obviously put into generating your benchmarks and data does not preclude your work from being poked-and-prodded, questioned and criticized.

    [0] https://github.com/dotnet/runtime/blob/main/docs/design/spec...

    [1] I am furthermore not sure if you run the same CLR/IL; the mono-3 vs mono-5 seem to be using different versions of your OBXMC as indicated by the different dates that seem to correspond to version numbers for the other things benchmarked?

    [2] The variant with the Core i7-720QM if I remember correctly, slightly newer than yours, but probably even more susceptible to SpeedStep and thermal throttling.

  • Avalonia

    Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET Foundation community project.

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • FrameworkBenchmarks

    Source for the TechEmpower Framework Benchmarks project

  • The most comprehensive benchmarks to track are the TechEmpower benchmarks as they are open source so you can see what each framework is doing: https://github.com/TechEmpower/FrameworkBenchmarks/tree/mast...

    The benchmarks model simple, but real world scenarios. It has breakdowns by EF, Dapper (the StackOverflow "micro-ORM"), MySQL, PG, and raw ADO.NET.

    It should be noted that EF and EF Core are not the same thing; EF Core is more or less a full rewrite: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/

    Recent benchmarks have EF Core catching up to Dapper. You can read more about Microsoft's focus on performance for EF Core here: https://devblogs.microsoft.com/dotnet/announcing-entity-fram...

  • Oberon

    Oberon parser, code model & browser, compiler and IDE with debugger

  • > but absolutely not for Rust

    Right. Here are measurement results based on the Are-we-fast-yet benchmark suite: https://github.com/rochus-keller/Oberon/blob/master/testcase.... The version of the benchmark translated to C and compiled with GCC or CLANG -O2 runs about double as fast as the CLI/.NET version. Rust's performance is close to C. And before you say that Mono is slower than the CoreCLR have a look at these measurements: https://www.quora.com/Is-the-Mono-CLR-really-slower-than-Cor....

  • HonkPerf.NET

  • - Unfortunately LINQ is no match to Rust iterators which get easily vectorized. However, there are low-allocations and simd-ified implementations which might help with your goals. See https://github.com/asc-community/HonkPerf.NET

    After all, DDD requires special care when describing its domain definitions in code but you really don't have to go OOP route nowadays for the core logic of your applications. Also records and record structs make it very easy to define contracts and state on the go without having to go with tons of boilerplate I keep seeing in a very much DDD-oriented project my team is responsible for.

  • core

    .NET news, announcements, release notes, and more! (by dotnet)

  • Couple of notes:

    - Yes it’s cross platform. However, that does not include Winforms or WPF. Apparently the “multi-platform” in MAUI is “Android, iOS, macOS, and Windows” which means if you don’t care about Linux, you have a potential cross-platform UI option. However, the decision to not include Linux, while not really a terrible act in and of itself, does hint at a bit of the limits of Microsoft’s “friendliness” towards open source.

    - Dotnet Core makes async easy, and that’s great. However, when playing around with it, I did notice that it’s the kind of “async” where you need to manually yield if you are not heavily IO bound. It’s not quite idiot proof and you can cause a lot of trouble by holding it wrong. This is not any different from JS or Rust, but it’s worth noting.

    - Big eyeroll at the knock on Go regarding generics. I’ve written a lot of Go code and while I think adding generics will be helpful, I can think of exactly one place in existing code I definitely want to put generics after 1.18. It’s one thing to expound on C# language design, which I agree has its merits, but getting into tit for tat comparisons with other languages that have vastly different design goals like Rust and Go is losing enough nuance to be basically meaningless, and then using that to elevate your opinion is just poor form.

    - Friendliness towards open source is still sketchy. They did indeed do most of the important things, including, well, move almost everything into the open. Well, almost.

    But not quite. Not the debugger for example. See this long-standing issue for some backstory: https://github.com/dotnet/core/issues/505

    Microsoft seems to have a tendency to do this. They give you almost everything, but they hold back some important components. It’s the same with VSCode; try using VSCode OSS. No remoting, no liveshare, no official extension repo. Mozilla doesn’t lock off access to AMO from Firefox forks. Chrome doesn’t lock block access to Webstore from Chromium or its forks. Open source Firefox can log into Sync. Open source Chromium can log into Sync, too. Open source Edge… well, no. Edge is closed source.

    Microsoft is indeed not the company that it was under Ballmer. That’s not all sunshine and rainbows, though.

    For what it’s worth, I’m not saying that Microsoft is obligated to do anything, or that we’d be better if they never changed. Even vscode-oss and monaco editor are quite nice to have. That said, Microsoft bills themselves as being allies of open source when I feel like this is a pretty dubious position. They’re clearly operating very strategically here; here is little guise of actual goodwill.

    At risk of sounding like a nut job, I suspect MAUI not supporting Linux is perfect to go alongside WSL2. From my perspective, Microsoft doesn’t seem to just want to mutually benefit from open source in the traditional way, they also seem interested in trying to shift the community in a certain direction where Windows and Microsoft binary blobs are an important part of open source developers toolkits. A slowly increasing number of killer features will rely on closed source blobs, allowing Microsoft to exert substantial control over the ecosystem, while still maintaining the ability to say “why are you so afraid? VS Code is open source*!”

    I still use VS Code despite my concerns, so I’ll leave it up to you to decide what that says about me.

  • OperationResult

    Rust-style error handling for C#

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • CliFx

    Class-first framework for building command-line interfaces

  • CliWrap

    Library for running command-line processes

  • atldotnet

    Fully managed, portable and easy-to-use C# library to read and edit audio data and metadata (tags) from various audio formats, playlists and CUE sheets

  • awesome-dotnet

    A collection of awesome .NET libraries, tools, frameworks and software

  • js-ts-csharp

    A repository demonstrating functional techniques with C# 10 and the similarities between JavaScript, TypeScript, and C#.

  • .NET and C# as a platform are evolving extremely fast compared to many other runtimes and languages. In fact, it's kind of been converging with JavaScript and TypeScript. I have a small repo here that highlights this: https://github.com/CharlieDigital/js-ts-csharp

    If you stopped working with .NET and C# around version 4, the language itself has transformed.

    Local functions, pattern matching, records, and more!

  • sdk

    Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI (by dotnet)

  • If you’re just looking to be unblocked, use the Web SDK because you’re building and running combined web + hosted services [1]. The section linked shows the precise difference between the Web and Worker SDKs for hosted services.

    If you’re looking for docs on what all the SDKs are/do, and their source code, start here [2].

    If you’re looking to just add the asp net core packages/apis to your basic sdk/console project, here [3]. But note that your app build/publish probably won’t work 100% because msbuild won’t be configured to do so.

    If you want to fix that manually (i.e do what the Web SDK does automatically), You can use the Web SDK props file as a starting point [4]. (Linked to in [2])

    It seems well documented to me, but you’re welcome to propose new docs to the aspnet docs team. They’re very responsive [5].

    [1] https://docs.microsoft.com/en-us/aspnet/core/fundamentals/ho...

    [2] https://docs.microsoft.com/en-us/dotnet/core/project-sdk/ove...

    [3] https://docs.microsoft.com/en-us/aspnet/core/fundamentals/ta...

    [4] https://github.com/dotnet/sdk/blob/ee98c8c25188195fd4f8a145b...

    [5] https://github.com/dotnet/AspNetCore.Docs

  • AspNetCore.Docs

    Documentation for ASP.NET Core

  • If you’re just looking to be unblocked, use the Web SDK because you’re building and running combined web + hosted services [1]. The section linked shows the precise difference between the Web and Worker SDKs for hosted services.

    If you’re looking for docs on what all the SDKs are/do, and their source code, start here [2].

    If you’re looking to just add the asp net core packages/apis to your basic sdk/console project, here [3]. But note that your app build/publish probably won’t work 100% because msbuild won’t be configured to do so.

    If you want to fix that manually (i.e do what the Web SDK does automatically), You can use the Web SDK props file as a starting point [4]. (Linked to in [2])

    It seems well documented to me, but you’re welcome to propose new docs to the aspnet docs team. They’re very responsive [5].

    [1] https://docs.microsoft.com/en-us/aspnet/core/fundamentals/ho...

    [2] https://docs.microsoft.com/en-us/dotnet/core/project-sdk/ove...

    [3] https://docs.microsoft.com/en-us/aspnet/core/fundamentals/ta...

    [4] https://github.com/dotnet/sdk/blob/ee98c8c25188195fd4f8a145b...

    [5] https://github.com/dotnet/AspNetCore.Docs

  • SaaSHub

    SaaSHub - Software Alternatives and Reviews. SaaSHub helps you find the best software and product alternatives

    SaaSHub logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts