Most active commenters
  • EVa5I7bHFq9mnYK(4)
  • neonsunset(4)

←back to thread

201 points olvy0 | 11 comments | | HN request time: 0.001s | source | bottom
Show context
EVa5I7bHFq9mnYK ◴[] No.41879253[source]
It's a shame, actually, that .NET performance improvements of up to x1000 could still be found after two decades and hundreds of millions spent on development.
replies(2): >>41879332 #>>41879654 #
1. eknkc ◴[] No.41879654[source]
Most of the time, it is not because there were too many slow things to be improved, it is mostly because they are adding more facilities to the runtime, enabling other performance improvements.

For example, the ReadOnlySpan type is a recent addition to the runtime and it will allow faster iterations when used. They simply enabled Linq to use it now.

replies(1): >>41880338 #
2. EVa5I7bHFq9mnYK ◴[] No.41880338[source]
ReadOnlySpan is a breakthrough innovative data structure, consisting of a pointer and a _length, that took Microsoft Corporation two decades to invent.

Well, better late than never.

replies(2): >>41880387 #>>41883634 #
3. neonsunset ◴[] No.41880387[source]
other languages do not have special pointers that can point to GC object interiors, be transparently addressed with arithmetics and cooperatively updated by GC without pinning, while also allowing to point to stack and unmanaged memory
replies(2): >>41880551 #>>41880632 #
4. EVa5I7bHFq9mnYK ◴[] No.41880551{3}[source]
I see, thanks. Still, x1000 performance improvement is called a bug fix.
replies(1): >>41884307 #
5. int_19h ◴[] No.41880632{3}[source]
But those pointers were around since .NET 1.0. Not only that, but things like e.g. ArgIterator were also there! Span could have been there too; it was really a matter of design rather than technical capability.

I think the main reason why C# didn't have this (and other low-level features like plain function pointers) for so long is because the original vision for .NET was that you'd mix and match different languages in your project as needed. So if you needed that kind of stuff, you'd reach out for managed C++ (and later, C++/CLI), while C# was kept deliberately more high-level.

And so once that approach was abandoned, C# needed to catch up to be able to play the "one language that can do it all" role.

replies(1): >>41884233 #
6. koyote ◴[] No.41883634[source]
Given that it took C++ a similar amount of time to invent the string specific string_view I don't think it's as simple as you're making it out.

ReadOnlySpan is so powerful because it can be used generically and has implicit conversions that allow you to improve the speed of existing methods without breaking backwards compatibility.

It's well designed and that takes thought and time.

7. neonsunset ◴[] No.41884233{4}[source]
'ret T's aka byref pointers aka managed references in their current form is a relatively recent addition. I can't seem to find which exact version but if my memory is correct - around .NET 5 or so, before that e.g. Spans had to use a specially annotated field with [ByRefLike] attribute. There wasn't really such a forefront support in both the language and the runtime to enable the user scenarios and even, if limited, ref escape analysis that are possible today. .NET 9 goes further and allows types that hold byrefs to be generic arguments, so you can now handroll your own "true" span-based LINQ-like code as well.
replies(1): >>41898827 #
8. neonsunset ◴[] No.41884307{4}[source]
I encourage you to read through this section: https://devblogs.microsoft.com/dotnet/performance-improvemen... and go through the pull requests that it references.

The Nx elements figure is a speedup you would expect if you introduce a shortcut to any algorithm that can bypass doing full iteration, and >100x speed-up is what you would expect from going from interface dispatch per element (even if devirtualized behind a guard) to a bespoke vectorized implementation.

Even if you happen to have irrational dislike of .NET, this is still useful learning material and perfectly applies to other languages that expose similar functionality (provided they have sufficiently good type system and generics).

replies(1): >>41904122 #
9. int_19h ◴[] No.41898827{5}[source]
The ability to have managed references as fields in types dates all the way back to 1.0. What's new is the ability to define custom ref types in verifiable code, but the runtime itself could always do so on a case by case basis - that is how TypedReference, ArgIterator etc have always worked.
10. EVa5I7bHFq9mnYK ◴[] No.41904122{5}[source]
An algorithm that performs a full iteration where a single lookup is sufficient, is a very bad algorithm. An iterator implementation that introduces 100x overhead is a very bad implementation. C++ has types and generics and pipes and is pretty efficient.
replies(1): >>41908714 #
11. neonsunset ◴[] No.41908714{6}[source]
C++ is absolutely terrible at this, either UX or performance (or sometimes both), and it's not even close ;)