Тёмный
No video :(

Solving One of the Biggest Array Issues in C# 

Nick Chapsas
Подписаться 300 тыс.
Просмотров 35 тыс.
50% 1

Check out my new course From Zero to Hero: Logging in .NET and use code LOG20 at checkout for 20% off: bit.ly/logging... 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/nickwor...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasG...
Follow me on Twitter: bit.ly/ChapsasT...
Connect on LinkedIn: bit.ly/ChapsasL...
Keep coding merch: keepcoding.shop
#csharp #dotnet

Опубликовано:

 

21 авг 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 80   
@MZZenyl
@MZZenyl Год назад
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 Год назад
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 Год назад
Please do a video on ConfigureAwait. Thanks
@MRender32
@MRender32 Год назад
yeah especially since .NET 8 got a ConfigureAwaitOptions enum overload
@peryvindhavelsrud590
@peryvindhavelsrud590 Год назад
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 Год назад
@@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 Год назад
@@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.
@sonpham7617
@sonpham7617 Год назад
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 Год назад
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 Год назад
I actually never understand the reason for providing all those methods to modify IMMUTABLE Array. IReadOnlyCollection is far better
@Rob_III
@Rob_III Год назад
@@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 Год назад
@@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.
@Stdvwr
@Stdvwr Год назад
Why would you create an array just to cast it to immutable array? Why not ToImmutableArray directly from the enumerable? What about ImmutableArray.Builder?
@justwatching6118
@justwatching6118 Год назад
OFC.. I would really like that you create a (possible longer) video on unsafe :D
@peryvindhavelsrud590
@peryvindhavelsrud590 Год назад
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.
@codeyhuntting8830
@codeyhuntting8830 Год назад
Love the polite frankness at 0:09 - "If you've never used immutable array, then... I'm a bit about that" XD
@user-tk2jy8xr8b
@user-tk2jy8xr8b Год назад
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 Год назад
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 Год назад
@@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
@F1nalspace
@F1nalspace Год назад
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 Год назад
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 Год назад
Dangling pointers are so much fun
@cn-ml
@cn-ml Год назад
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.
@phoenixwyllow
@phoenixwyllow Год назад
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...
@kpamafrederic6558
@kpamafrederic6558 Год назад
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
@the-niker
@the-niker Год назад
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.
@zwatotem
@zwatotem Год назад
I just noticed the background image of your logging course 😂
@feefifofum6383
@feefifofum6383 Год назад
So is it quicker to loop over immutable arrays compared to normal arrays?
@justwatching6118
@justwatching6118 Год назад
Yeah.. I've seen a LOT of times people over abusing lists (use them for every type of collection)..
@YuraSuper2048
@YuraSuper2048 Год назад
Please make a video about unsafe it seems very fun
@MRender32
@MRender32 Год назад
nice! i thought this would be about collection literals, pleasantly surprised
@Eduardoo
@Eduardoo Год назад
I'm surprised that frozen collections weren't mentioned in the video
@JustinLampe
@JustinLampe Год назад
A new Rider EAP with AI integration. We need a video for this!
@Palladin007
@Palladin007 Год назад
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?
@kingumosama
@kingumosama Год назад
It was very helpful information. Thank you so much.
@nanvlad
@nanvlad Год назад
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 Год назад
It does not have setter, so such operation is just not possible
@inzyster
@inzyster Год назад
Interesting stuff, definitely useful for some of my projects.
@Crozz22
@Crozz22 Год назад
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 Год назад
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 Год назад
@@nickchapsas Just because .NET collection interfaces make no sense whatsoever, doesn't mean Immutable represents the intent better (I don't think it does).
@figloalds
@figloalds Год назад
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
@leandroteles7857
@leandroteles7857 Год назад
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 Год назад
Thanks for explaining!
@alexanderkvenvolden4067
@alexanderkvenvolden4067 Год назад
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 Год назад
Another bonus is that it avoids boxing the result. Using reflection would return the ImmutableArray as an Object.
@jonasgranlund4427
@jonasgranlund4427 Год назад
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 Год назад
I think I'll do a video about all these types because people seem to largely misunderstasnd them and misuse them
@SeanAlunni
@SeanAlunni Год назад
If the "ImmutableCollectionsMarshal" actually calls the internal constructor, how does it manage to not allocate any byte?
@paarma1752
@paarma1752 Год назад
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.
@urbanelemental3308
@urbanelemental3308 Год назад
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.
@Dustyy01
@Dustyy01 Год назад
More unsafe stuff🎉
@lordshoe
@lordshoe Год назад
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 Год назад
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 Год назад
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 Год назад
@@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.
@fehmidenguir6278
@fehmidenguir6278 Год назад
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 Год назад
It is built in out of the box in Rider
@Lubgi3
@Lubgi3 Год назад
Can’t we return ReadOnlySpan for that purpose? Is there any difference?
@nickchapsas
@nickchapsas Год назад
ReadOnlySpan is a ref struct so it can only be stack allocated which limits where it can be used
@neociber24
@neociber24 Год назад
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
@kaiserbergin
@kaiserbergin Год назад
feels like ReadOnlyArray - but I'll take it!
@danyafulenwider8530
@danyafulenwider8530 10 месяцев назад
=
@danyafulenwider8530
@danyafulenwider8530 10 месяцев назад
😊 why does my array embroidery machine just stop in the middle of a project😊 0:00 0:00
@Mitakbacktrack
@Mitakbacktrack Год назад
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.
@AlFasGD
@AlFasGD Год назад
And as always, keep coding unsafely
@EddieDemon
@EddieDemon Год назад
Haha, “tl;dw” 😂
@user-zk5ym9ut1j
@user-zk5ym9ut1j Год назад
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 Год назад
the only valid array type is T* where T : unmanaged
@Bliss467
@Bliss467 Год назад
Why do we use properties with public get set instead of just a public field? It seems like a completely superfluous wrapper
@ryanzwe
@ryanzwe Год назад
:o
@anomalii7720
@anomalii7720 Год назад
So you have an immutableArray, you copy into a mutable Array and you have the same problem.
@dmitrykim3096
@dmitrykim3096 Год назад
I think you had to choose c++, you spend a lot of time on a lower level optimizations and hacks with C#.
@robbielowe2516
@robbielowe2516 Год назад
🌸 Promo'SM
@dukefleed9525
@dukefleed9525 Год назад
ImmutableCollectionMarshal.AsArray looks the best way ever to shoot yourself in the foot.
@mrwensveen
@mrwensveen Год назад
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 Год назад
I have never encountered this issue, because IReadOnlyList exists :)
@nickchapsas
@nickchapsas Год назад
Very different thing
Далее
Writing C# without allocating ANY memory
19:36
Просмотров 147 тыс.
What is Span in C# and why you should be using it
15:15
PEDRO PEDRO INSIDEOUT
00:10
Просмотров 2,4 млн
The Right Way to Check for Null in C#
9:35
Просмотров 96 тыс.
3 .NET "Best Practices" I Changed My Mind About
10:16
Просмотров 102 тыс.
Stackalloc and Spans
30:17
Просмотров 10 тыс.
Releasing Features the Smart Way in .NET
15:28
Просмотров 49 тыс.
Optimizing String Performance Easily in C#
12:02
Просмотров 41 тыс.