Solving One of the Biggest Array Issues in C#

  Рет қаралды 33,844

Nick Chapsas

Nick Chapsas

11 ай бұрын

Check out my new course From Zero to Hero: Logging in .NET and use code LOG20 at checkout for 20% off: bit.ly/loggingdotnet valid for the first 400 purchases!
Become a Patreon and get source code access: / nickchapsas
Hello, everybody, I'm Nick, and in this video, I will show you how you can solve the biggest issue with Immutable Array's performance in C# and .NET.
Workshops: bit.ly/nickworkshops
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasGitHub
Follow me on Twitter: bit.ly/ChapsasTwitter
Connect on LinkedIn: bit.ly/ChapsasLinkedIn
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 81
@MZZenyl
@MZZenyl 10 ай бұрын
Unsafe (the class), unsafe (the keyword), P/Invoke, and other topics relating to marshalling and manual memory management, is always good fun. For most people, using these is rarely if ever necessary (especially now that we have the Memory and Span structs), but they're a great learning opportunity that can lead to a much deeper understanding of what actually makes .NET tick.
@davidmartensson273
@davidmartensson273 10 ай бұрын
Yes, same with reflection, you can cause some very interesting errors :P My favorit was "if(a == 0) ..." causing null reference exception. And yes it was the comparisson and no there was not overloaded operators, just comparing and int variable with zero triggered null ref. And a was an argument to the function "... MyFunc(int a) { ..." You cannot do that without some serious deep diving into the dark corners of C#.
@cdarrigo
@cdarrigo 10 ай бұрын
Please do a video on ConfigureAwait. Thanks
@MRender32
@MRender32 10 ай бұрын
yeah especially since .NET 8 got a ConfigureAwaitOptions enum overload
@peryvindhavelsrud590
@peryvindhavelsrud590 10 ай бұрын
Hopefully ConfigureAwait is soon to be deprecated except for the rare circumstances where you need to use ConfigureAwait(true); which, if my understanding is correct, only applies for UI thread async operations.
@axelbreekweg
@axelbreekweg 10 ай бұрын
@@peryvindhavelsrud590ConfigureAwait(true) is the default. So if you were to omit this, it’s still always configured this way. And yes, for technologies like WinForms and WPF this is important since it has a UI thread. You need to make sure the continuation task is taken by the UI thread. In these environments ConfigureAwait is relevant, you could use ConfigureAwait(false) if you wish that any other thread than the UI thread can continue the task.
@peryvindhavelsrud590
@peryvindhavelsrud590 10 ай бұрын
@@axelbreekweg my point being that it should be possible to alter the default to ConfigureAwait(false) per project, so my libraries by default have the desired behaviour so i don't have to write it everywhere.
@codeyhuntting8830
@codeyhuntting8830 10 ай бұрын
Love the polite frankness at 0:09 - "If you've never used immutable array, then... I'm a bit about that" XD
@sonpham7617
@sonpham7617 10 ай бұрын
It's interesting with ImmutableArray, but it causes potential issues if somebody without these knowledge or by mistake use add or remove method, which creates a whole new array. I think IReadOnlyList and IReadOnlyCollection would be better which dont provide add or remove method.
@urbanelemental3308
@urbanelemental3308 10 ай бұрын
I'm in agreement here. I know there can be some performance degradation when accessing an interface and not just the struct, but in this case, I would definitely make a new struct like ReadOnlyArray that makes it clear that the underlying values can change (by the owner) but cannot be changed by the consumer.
@anm3037
@anm3037 10 ай бұрын
I actually never understand the reason for providing all those methods to modify IMMUTABLE Array. IReadOnlyCollection is far better
@Rob_III
@Rob_III 10 ай бұрын
@@anm3037 An immutable structure is useful for when multiple threads are accessing the items in it for example. You have the guarantee that nobody is modifying the array while a bunch of threads are modifying it. But that doesn't mean you may don't want to modify the array; so there are methods that do that for you by making a copy of the array and meanwhile everything keeps working nicely and it's up to you to decide if/when you want to use the new ("modified") array.
@anm3037
@anm3037 10 ай бұрын
@@Rob_III I disagree with that. Immutable array should not expose such methods. And unfortunately, there is no other contiguous memory that behaves like ReadOnlyCollection.
@justwatching6118
@justwatching6118 10 ай бұрын
OFC.. I would really like that you create a (possible longer) video on unsafe :D
@user-tk2jy8xr8b
@user-tk2jy8xr8b 10 ай бұрын
Most of the time, IReadOnlyList is the right type for the right job, not ImmutableArray. Btw, several years ago we rewrote some pieces of the application to use Immutable* types. Later, after profiling, we rewrote them back to Dictionary/HashSet/List+IReadOnly* because of poor access time (log vs const) and memory cost (a tree obviously consumes more memory than a hash table, plus worse localization leads to CPU cache misses, but that's more in theory than in practice), both of which were important for the app. Immutable arrays are an exception here, because they are optimal by both space and time (even better than IReadOnlyList as interface calls are heavier, with the v-table linear search unless I'm mistaking about that). However, ImmutableArray has one functional downside when compared to IReadOnlyList: it implements ICollection and IList which violates the Liskov substitution principle, so good luck calling `void Add(T)`
@fluffydoggo
@fluffydoggo 9 ай бұрын
Keep in mind ICollection and IList have a IsReadOnly property, so that can be checked for if you really want to
@user-tk2jy8xr8b
@user-tk2jy8xr8b 9 ай бұрын
@@fluffydoggo yes, it's like using one interface for everything in your program, just use IsBehavior1, IsBehavior2 and so on to decide, what methods are supported by a particular instance
@peryvindhavelsrud590
@peryvindhavelsrud590 10 ай бұрын
I normally return Read-only Memory or ReadOnlySpan to handle these types. The fact that I'm able to re-retrieve a non Read-only version is a bit sus. The unsafe option is also a possibility for avoiding allocations, not sure if i see any real difference except for that the new Marshalling methods make it even easier to get the mutable array back.
@F1nalspace
@F1nalspace 10 ай бұрын
I have encounter that issue several times and always wanted a immutable array that just point to the backing array, so really thanks for sharing that ;-) I didn´t knew Unsafe.As() either... i really need to look into this, because i like unsafe stuff ^^
@FireDragon91245
@FireDragon91245 10 ай бұрын
if you like unsafe i have a neat fun fact you can actualy do unsafe class GenericPointer where T : unmanaged { public T* Ptr; } its posible to make generic pointers
@neociber24
@neociber24 10 ай бұрын
Dangling pointers are so much fun
@cn-ml
@cn-ml 10 ай бұрын
Honestly, i think the problem is a different one if your need to use this. If your application requieres you to access the backing field of the immutable collection, you shouldnt have used an immutable collection in the first place. Also, if your application requieres a fast immutable collection access without reallocation, i think you should make that clear using the api interface, using the AsReadOnly methods.
@the-niker
@the-niker 10 ай бұрын
Good stuff I can see it being used in cases where a method creates and fills an array dynamically but returns immutable version of it in the end and discards the original for zero additional cost.
@Stdvwr
@Stdvwr 10 ай бұрын
Why would you create an array just to cast it to immutable array? Why not ToImmutableArray directly from the enumerable? What about ImmutableArray.Builder?
@zwatotem
@zwatotem 10 ай бұрын
I just noticed the background image of your logging course 😂
@phoenixwyllow
@phoenixwyllow 10 ай бұрын
I believe quite a few libraries use the ToImmutableArray stuff to generate things once and some use it for exactly the purpose of ensuring the internal array doesn't mutate. I would love to have a clean immutable or readonly implementation specifically for initalizing (avoiding the creation of the first mutable array) so we don't have to resort to unsafe or Unsafe calls... I suppose in some cases it may just be worth forcing a breaking change in favour of ReadOnlyList, but sometimes that's just not possible or simply the wrong approach...
@kingumosama
@kingumosama 10 ай бұрын
It was very helpful information. Thank you so much.
@fehmidenguir6278
@fehmidenguir6278 10 ай бұрын
Hello Nick, thanks for the video. I wanted to ask how you can access the method implementation of the dotnet framework through your IDE ? Is it a plugin or it's supported out of the box. Also is it supported in Visual Studio
@nickchapsas
@nickchapsas 10 ай бұрын
It is built in out of the box in Rider
@kpamafrederic6558
@kpamafrederic6558 10 ай бұрын
All right. I'm definitely gonna need that video on Unsafe. I failed at converting a ReadOnlySpan to ReadOnlyMemory without new allocation 2 times now
@inzyster
@inzyster 10 ай бұрын
Interesting stuff, definitely useful for some of my projects.
@MRender32
@MRender32 10 ай бұрын
nice! i thought this would be about collection literals, pleasantly surprised
@feefifofum6383
@feefifofum6383 10 ай бұрын
So is it quicker to loop over immutable arrays compared to normal arrays?
@guiorgy
@guiorgy 10 ай бұрын
Isn't it simpler to just use a ReadOnlySpan(T[])? Does the ImmutableArray have any benefits that ReadOnlySpan does not?
@nickchapsas
@nickchapsas 10 ай бұрын
ReadOnlySpan is a ref struct so it can only be stack allocated which limits where it can be used
@nanvlad
@nanvlad 10 ай бұрын
What if I use users[0] = myVar? Does it create a new array for that or just replace first item with a new value?
@iamprovidence-xj5wf
@iamprovidence-xj5wf 10 ай бұрын
It does not have setter, so such operation is just not possible
@justwatching6118
@justwatching6118 10 ай бұрын
Yeah.. I've seen a LOT of times people over abusing lists (use them for every type of collection)..
@Dustyy01
@Dustyy01 10 ай бұрын
More unsafe stuff🎉
@alexanderkvenvolden4067
@alexanderkvenvolden4067 10 ай бұрын
Does this do the same thing as using reflection to call the internal constructor? I suppose the advantage to that is not relying on non-supported means which Microsoft could break without notice.
@phizc
@phizc 10 ай бұрын
Another bonus is that it avoids boxing the result. Using reflection would return the ImmutableArray as an Object.
@JustinLampe
@JustinLampe 10 ай бұрын
A new Rider EAP with AI integration. We need a video for this!
@YuraSuper2048
@YuraSuper2048 10 ай бұрын
Please make a video about unsafe it seems very fun
@leandroteles7857
@leandroteles7857 10 ай бұрын
It's worth noting that this only works because ImmutableArray is a struct. (An object reference and "a struct with an object reference" have the same memory representation)
@manilladrift
@manilladrift 10 ай бұрын
Thanks for explaining!
@Lubgi3
@Lubgi3 10 ай бұрын
Can’t we return ReadOnlySpan for that purpose? Is there any difference?
@nickchapsas
@nickchapsas 10 ай бұрын
ReadOnlySpan is a ref struct so it can only be stack allocated which limits where it can be used
@Palladin007
@Palladin007 10 ай бұрын
Honestly, what is the point of the ImmutableArray? Why not just IReadOnlyList? Well, you can cast back, but there is also a way to manipulate the ImmutableArray. Or what speaks against ReadOnlyMemory?
@Eduardoo
@Eduardoo 10 ай бұрын
I'm surprised that frozen collections weren't mentioned in the video
@lordshoe
@lordshoe 10 ай бұрын
So, how is it actually any more immutable than before if you can just get the backing array anyways? Or is it mostly just for the convenience it offers? I've never used ImmutableArray, but what benefits does it provide over exposing something like an IReadOnlyCollection?
@protox4
@protox4 10 ай бұрын
It's faster. Interfaces make iterating much slower. Those are unsafe methods, so you should not be using them in general code. They are safe if you use them correctly.
@nickchapsas
@nickchapsas 10 ай бұрын
It's the safety net it provides. You could always do something like user reflection and hack your way around the problem but that would have been inefficient. ReadOnly data structures and Immutable data structures are very different in C#. Maybe they deserve a video of their own
@yjagota
@yjagota 10 ай бұрын
@@nickchapsas I had the same question. A video on benefits of ImmutableArray over List or IReadOnlyList will be great. And thanks for all the great videos Nick. Keep up the good work.
@paarma1752
@paarma1752 10 ай бұрын
I have found that more often than not the exact requirement is not to map the dto from a single object, but actually from multiple. More often than not it's best to keep the dtos as the API for your domain logic (your domain logic digests a dto and then outputs another one). And this also means that your dtos should be part of your domain.
@Crozz22
@Crozz22 10 ай бұрын
I don't understand the point of this, you can just pass around an IReadOnlyList instead. Arrays implement IReadOnlyList. Considering you have to be careful to not change the backing array/list anyway with both approaches.
@nickchapsas
@nickchapsas 10 ай бұрын
Intent is the point. Why would you use a ReadOnlyLIST to represent an array that cannot be mutated and why would you give up on the ability to generate new immutable versions of that data structure by not using ImmutableArrays?
@chris-pee
@chris-pee 10 ай бұрын
@@nickchapsas Just because .NET collection interfaces make no sense whatsoever, doesn't mean Immutable represents the intent better (I don't think it does).
@urbanelemental3308
@urbanelemental3308 10 ай бұрын
I feel like it should be a different struct/class that is a wrapper around the array like a ReadOnlyArray or something like that. Allowing 'hacks' like this seems to break the intention.
@SeanAlunni
@SeanAlunni 10 ай бұрын
If the "ImmutableCollectionsMarshal" actually calls the internal constructor, how does it manage to not allocate any byte?
@neociber24
@neociber24 10 ай бұрын
I crashed programs so many times using unsafe that's how you know is fun 😂 I feel weird those marshal methods are not marked as unsafe
@jonasgranlund4427
@jonasgranlund4427 10 ай бұрын
Since It is so many comment regarding the IReadonlyList... instead of an ImmutableArray I have a feeling we will get a post about those in a near time :)
@nickchapsas
@nickchapsas 10 ай бұрын
I think I'll do a video about all these types because people seem to largely misunderstasnd them and misuse them
@figloalds
@figloalds 10 ай бұрын
I don't subscribe to this, to me this is like an extra pair of wheels on the bike of programmers who are bad And if I'm saying "ToImmutableArray" and this makes a whole copy, then it's not very different from handing back a modifiable copy array which the user function may need to alter anyways in it's own processing And besides, almost everything in OOP is references and I really doubt the "immutable" array makes the underlying objects any immutable, it's still shared state anyways, still requires common sense from the programmers writing the lib and user code
@kaiserbergin
@kaiserbergin 10 ай бұрын
feels like ReadOnlyArray - but I'll take it!
@danyafulenwider8530
@danyafulenwider8530 7 ай бұрын
=
@danyafulenwider8530
@danyafulenwider8530 7 ай бұрын
😊 why does my array embroidery machine just stop in the middle of a project😊 0:00 0:00
@EddieDemon
@EddieDemon 10 ай бұрын
Haha, “tl;dw” 😂
@AlFasGD
@AlFasGD 10 ай бұрын
And as always, keep coding unsafely
@user-zk5ym9ut1j
@user-zk5ym9ut1j 10 ай бұрын
Never seen any practical application of ImmutableArray for 7 years, a bit of HashSets here, a couple Queues there, but ImmutableArray is a bit confusing collection
@FireDragon91245
@FireDragon91245 10 ай бұрын
the only valid array type is T* where T : unmanaged
@ryanzwe
@ryanzwe 10 ай бұрын
:o
@Bliss467
@Bliss467 10 ай бұрын
Why do we use properties with public get set instead of just a public field? It seems like a completely superfluous wrapper
@dmitrykim3096
@dmitrykim3096 10 ай бұрын
I think you had to choose c++, you spend a lot of time on a lower level optimizations and hacks with C#.
@robbielowe2516
@robbielowe2516 10 ай бұрын
🌸 Promo'SM
@anomalii7720
@anomalii7720 10 ай бұрын
So you have an immutableArray, you copy into a mutable Array and you have the same problem.
@Mitakbacktrack
@Mitakbacktrack 10 ай бұрын
I think we can also use Array.AsReadOnly(_users). It uses 24 bytes for 10,000 iterations. It's slower - 2.4 ns vs. 0.0082 ns on the Smart() method.
@dukefleed9525
@dukefleed9525 10 ай бұрын
ImmutableCollectionMarshal.AsArray looks the best way ever to shoot yourself in the foot.
@mrwensveen
@mrwensveen 10 ай бұрын
My method isn't quite as fast as with Unsafe or ImmutableCollectionsMarshal trickery, but it is quite fast compared to AsImmutable: ImmutableArray.Empty.AddRange(_users!); About a 1000 times as fast and doesn't allocate memory (speed is constant so 100 or 10_000 items is similar). And it's totally safe! I swear!
@nataliasikorka4825
@nataliasikorka4825 10 ай бұрын
I have never encountered this issue, because IReadOnlyList exists :)
@nickchapsas
@nickchapsas 10 ай бұрын
Very different thing
C# 12's Secret Feature | .NET Tips 8
0:34
Nick Chapsas
Рет қаралды 28 М.
Forget Grafana And Prometheus! Start With This.
10:51
Nick Chapsas
Рет қаралды 38 М.
ХОТЯ БЫ КИНОДА 2 - официальный фильм
1:35:34
ХОТЯ БЫ В КИНО
Рет қаралды 1 МЛН
Do you have a friend like this? 🤣#shorts
00:12
dednahype
Рет қаралды 9 МЛН
Why? 😭 #shorts by Leisi Crazy
00:16
Leisi Crazy
Рет қаралды 28 МЛН
The New Best Way To Search for Values in .NET 8
11:05
Nick Chapsas
Рет қаралды 68 М.
Stackalloc and Spans
30:17
Coding Tutorials
Рет қаралды 8 М.
I Lied! The Fastest C# Loop Is Even Weirder
11:50
Nick Chapsas
Рет қаралды 45 М.
Collections Just Changed in C# 12 and That’s Good
8:01
Nick Chapsas
Рет қаралды 103 М.
Await Async Tasks Are Getting Awesome in .NET 9!
9:24
Nick Chapsas
Рет қаралды 82 М.
Why You Might Not Need Interfaces in C# 12
12:43
Nick Chapsas
Рет қаралды 66 М.
the new PS4 jailbreak is sort of hilarious
12:21
Low Level Learning
Рет қаралды 365 М.
The High Performance Types You Ignored for Years in .NET
10:14
Nick Chapsas
Рет қаралды 44 М.
Swagger is Going Away in .NET 9!
10:48
Nick Chapsas
Рет қаралды 62 М.
ХОТЯ БЫ КИНОДА 2 - официальный фильм
1:35:34
ХОТЯ БЫ В КИНО
Рет қаралды 1 МЛН