Fixing the performance problem of enums in C#

  Рет қаралды 50,560

Nick Chapsas

Nick Chapsas

Жыл бұрын

Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Check out my workshops:
NDC Oslo: bit.ly/ndcoslo2022nick1
NDC Minessota: bit.ly/ndcminne2022nick1
NDC Syndey: bit.ly/ndcsydney2022nick1
Hello everybody I'm Nick and in this video I will show you how you can easily fix all the performance issues that enums suffer from. As always, performance is contextual, but you should know what you optimize when the time comes to optimize.
Give EnumGenerators a star on GitHub: github.com/andrewlock/NetEsca...
Check out Andrew’s blog: andrewlock.net
Previous enum video: • C#'s Enum performance ...
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

Пікірлер: 164
@nickchapsas
@nickchapsas Жыл бұрын
Because it's not clear, at 10:20 I don't mean that it should be cached as an array and returned as an array, rather cached as an immutable array using the ImmutableArray type and then exposed to the user as an IEnumerable to consume as they like. EDIT: Andrew wants to keep the Get methods to return an array as a drop in replacement. We are talking in this PR to see how we can optimize it without breaking the signature and mutating the data: github.com/andrewlock/NetEscapades.EnumGenerators/pull/21
@phizc
@phizc Жыл бұрын
Since it is a list type it'd be better to return it as such. By returning an IEnumerable you remove functionality unnecessarily.
@nickchapsas
@nickchapsas Жыл бұрын
@@phizc Like what? You can't add or remove data (which is what a list adds on top of collection/enumerable) so the whole list argument isn't valid.
@AnonymRetard
@AnonymRetard Жыл бұрын
@@nickchapsas You lose the ability to access elements by index and accessing the Count of elements without type-casting back to a list or by uneccessarily enumerating. Instead you can return an IReadOnlyList.
@phizc
@phizc Жыл бұрын
@@nickchapsas what Alexander said. Count and index lookup. I'm on my phone so it was inconvenient to look up the correct types.
@nickchapsas
@nickchapsas Жыл бұрын
That's part of ICollection not IList. Andrew wants to keep it as an array btw so the contract doesn't break so we are tring to think of a way to optimize it while still returning an array
@DaddyFrosty
@DaddyFrosty Жыл бұрын
The “The Cherno” of C#. I love that you consider perf and allocs and don’t just act like it’s not a thing. Haven’t seen a single C# video tutorial that mentions allocs for what they are doing.
@azmanic
@azmanic Жыл бұрын
C# devs are very annoying for this, "That's premature optimisation!!!!!!!!". Yes, shaving 0.25ms off a method called once in a blue moon is bad, that doesn't mean you shouldn't care about the performance of what you're doing at all. We definitely need more of this performance conscious stuff in the C# community.
@Velociapcior
@Velociapcior Жыл бұрын
@@azmanic the thing is, you never know how many times method will be called when you implement it. So optimization should be always a consideration. I started using Nicks tips and tricks in my commercial work and I already had to explain what I'm doing to my "senior" colleagues, when they reviewed my code
@CameronOwen101
@CameronOwen101 Жыл бұрын
Yeah it's nice - I mostly use C# for Unity so while I'm constrained to C# 7 right now and not all Nick's content is something I can currently apply, the performance focus is nice because for games and multiplayer servers at scale some things really do matter.
@azmanic
@azmanic Жыл бұрын
@@CameronOwen101 Yes very much so, sadly Unity is stuck on its own Mono branch so it misses some things. For example you can now stackalloc [] to a span within safe code. It's stuff like that we need more of, I guess that's why Unity made Burst despite C# now having SIMD.
@DaddyFrosty
@DaddyFrosty Жыл бұрын
@@CameronOwen101 yeah I’m also doing game dev but in s&box, think Garry’s mod 2. I used to run a large server on Garry’s mod and so I know how important optimisations are.
@asedtf
@asedtf Жыл бұрын
That flex changing Azure to AWS
@ogy23
@ogy23 Жыл бұрын
@AvenDonn Giga chad move
@BadgersEscape
@BadgersEscape Жыл бұрын
The original C# team actually referred to its enums as "one of the biggest mistakes in C#". It's because they are two things at once: Enumerations of fixed values (e.g. weekdays) AND value flags (where you bit-OR together multiple values). Since these two use-cases are in fact completely distinct in purpose, they should have been designed as two separate types in the type system. Mashing them into one and trying to make it familiar looking to old C programmers was a terrible idea in hindsight. It is a little known fact that the order you declare your fields in a C# file actually *does* matter and can be detected in a spec-compliant way. So I have implemented my own Enum type which resembles the Enums from Java. I made a generic "SmartEnum" base class which you can inherit from, and in your child class you can just declare your desired "enum fields" - and just like for regular enums, they will be automatically indexed based on their lexical order, and it provides all the desirable methods for getting the name, index, sorting, etc of your enum values that you could want (performant ofc). And just like Java enums you can add whatever extra data and methods you want to your enums. All fully spec compliant and auto-initialized. No hacks. If you search SO for C# spec initialization order of partial C# classes you will find me ;) Dig a bit further and you will find my Enums (best version is in a beta branch).
@jamesbennett5421
@jamesbennett5421 Жыл бұрын
I love that the Nick’s Random Number Generator only has 2 values.
@dadcraft9949
@dadcraft9949 Жыл бұрын
The community deserves a supercut of every 69 in Nick's videos. "A random number" [perfectly straight face]
@kmorosiuk
@kmorosiuk Жыл бұрын
69 and 420 in the same video... Well played Sir. Well played.
@Jussoparkours
@Jussoparkours Жыл бұрын
I came for in depth C# Enum knowledge, I stayed for the juicy int/Enum cast memes.
@manofqwerty
@manofqwerty Жыл бұрын
The two numbers chosen for the examples have me in stitches!
@swedishprogrammer
@swedishprogrammer Жыл бұрын
Great video Nick, thanks for sharing!
@transcendtient
@transcendtient Жыл бұрын
I've written an enum-like system using reflection that uses const member names in a class as labels and assigns integers at runtime. I use it to be able to use constant labels with an array without having holes in the indexing.
@nicktech2152
@nicktech2152 Жыл бұрын
Nick in every performance related videos: SOURCE GENERATORS!!!
@marvinbrouwer459
@marvinbrouwer459 Жыл бұрын
I know we're generally not concerned about disk space these days. Especially not on a cloud instance. However, I'd still like to see the number of bytes your binaries grow when using things like this. Just for the complete picture.
@MRender32
@MRender32 Жыл бұрын
Hopefully it can be trimmed off
@CrippleX89
@CrippleX89 Жыл бұрын
3:00 this is not the first time I've noticed you using 69 and 420 ;-)
@caiuxo
@caiuxo Жыл бұрын
indeed, always find it funny lol
@muhamedkarajic
@muhamedkarajic Жыл бұрын
As always great video!
@michaelhochriegl9501
@michaelhochriegl9501 Жыл бұрын
I too can highly recommend the blog from Andrew. With his awesome blog series about Source Generators I started my own project to implement the Object Builder pattern with less manual code to write. My package is still in pre-release state but I wouldn't be this far if it wasn't for Andrew Lock.
@IgnoreSolutions
@IgnoreSolutions Жыл бұрын
The only current problem child for me would be Enum.ToString(), and even then I mostly use that in logging and usually have some kind of cached string[] for "friendly/pretty" display of enum values. Still, a great video and a great example of source generation in C#! Hot take: I wish C# had C-like macros sometimes ;)
@luanalbuquerque5073
@luanalbuquerque5073 Жыл бұрын
a amazing video right on my birthday! thankyou man rsrsrs
@nickchapsas
@nickchapsas Жыл бұрын
This one is dedicated to you Luan
@luanalbuquerque5073
@luanalbuquerque5073 Жыл бұрын
@@nickchapsas 😍😍
@p4xx07
@p4xx07 Жыл бұрын
Hi Nick! I've been following you for over a year. I just wanna thank you for all of the quality content. I managed to land an amazing c# position just because I knew about Span from your videos, I knew everything about it without ever using it lol Thanks for your videos!
@nickchapsas
@nickchapsas Жыл бұрын
So glad you enjoy them
@saniel2748
@saniel2748 Жыл бұрын
I wish you could put extension method for enums directly into enum definition. It's annoying to create EnumNameExt class each time I intend some functionality for enum, like converting enum to color using ToColor() extension
@nickchapsas
@nickchapsas Жыл бұрын
One of the few things I miss from Java
@_grigoryta
@_grigoryta Жыл бұрын
You can define a static class in the same file as the enum. It works ok as long as you make extension methods only
@saniel2748
@saniel2748 Жыл бұрын
@@_grigoryta This is exactly what I do. Putting inside definition would make more sense though
@PietervandenHombergh
@PietervandenHombergh Жыл бұрын
Indeed the Java enum is way better. Each value is an object there, the ID is the index in an array and the name is a string field. That simpler implementation brings a lot of advantages. Each value can reimplement any of the defined methods.
@saniel2748
@saniel2748 Жыл бұрын
@@PietervandenHombergh Simpler implementation? C# enums are literally integers with names, you can't be simpler than this Enums in C# are fine, I never in my life want to use hashSet for flags like Java forces you to
@michaelsutherland5848
@michaelsutherland5848 Жыл бұрын
TIL light green is a nice color.
@Dustyy01
@Dustyy01 Жыл бұрын
Could u compare that library with FastEnums? Would be interesting to see the differences
@ronsijm
@ronsijm Жыл бұрын
Pretty cool. I'm wondering if the difference in file size becomes an issue at some point, doing this with too many enums. It doesn't matter much for most desktop/server applications, but I don't want to blow up the size of my Blazor of Lambda apps
@rafaelurrea2385
@rafaelurrea2385 Жыл бұрын
For anyone using this, how weird does it get when looking for the usages. I guess we would need to exclude the generated code somehow from that index in the IDE
@spl45hz
@spl45hz Жыл бұрын
The new array makes sense if you want to modify it. So I would make an additional method for a static/cached one.
@nickchapsas
@nickchapsas Жыл бұрын
There is no reason for this array to be modifiable, which is why Andrew is returning a new one every time. I'd rather it was cached in an ImmutableArray behind the scenes and returned as a IEnumerable for the user to consume any way they want
@TheBurzhuy
@TheBurzhuy Жыл бұрын
I've heard an opinion that huge switches pollute CPU cache. I even saw some articles but with integers arrays, basic operation of setting item of array in loop have noticeable op/s drop right on size of caches (L2/L3). So cache is something you need to be aware of in apps that work 24/7 on high load. Of course it depends on CPU. We do similar thing in project in which I'm working - enum-to-string transformation.
@phizc
@phizc Жыл бұрын
It can, but it has to be huge. Especially with these switches. E.g. in ToStringFast it creates a jump table where each "entry" only sets the address for the string to the "result" register and returns. That's something like 10-12 bytes per case. With 1000 cases it's still less than 16kb. It'd be more efficient if it just looked up the address of the string in a "const" array and returned that, but that is at runtime/JIT level.. The IsDefined method could be better when the enum is contiguous: return (int)color is >= 0 and
@TheBurzhuy
@TheBurzhuy Жыл бұрын
@@phizc Would it be better to have a static readonly string[] and enum's integer value as index in this array?
@gabrielsoloman5000
@gabrielsoloman5000 Жыл бұрын
LightGreen... NICE!
@BlazDGuitar
@BlazDGuitar Жыл бұрын
69...420, Nice.
@alejandroguardiola9085
@alejandroguardiola9085 Жыл бұрын
This awesome, I want to point out that caching the array of enums is not a viable solution unless you return an immutable kind of collection, because arrays are mutable in C#.
@alejandroguardiola9085
@alejandroguardiola9085 Жыл бұрын
My bad I just saw your comment
@Zenima
@Zenima Жыл бұрын
10:20 Arrays are not immutable, returning the same one can be problematic. Of course ReadOnlySpan or similar could be used, but then it's not the same interface as the original. :(
@nickchapsas
@nickchapsas Жыл бұрын
I never suggested that this should stay as an array when exposed to the user. It can easily be turned into a ImmutableArray or ImmutableList and exposed as an IEnumerable to the users to consume as they like.
@der.Schtefan
@der.Schtefan Жыл бұрын
@@nickchapsas That is not entirely correct. You suggest to keep it as an Array that is in a backing field at 10:30-10:40. But I agree, I think he could break the interface here without anybody complaining.
@AlanDarkworld
@AlanDarkworld Жыл бұрын
Ok, good stuff! The big question though is: why is the C# compiler doing anything else than what this custom source generator is doing? It seems like the only reasonable choice.
@MRender32
@MRender32 Жыл бұрын
Source generators are relatively new compared to .NET’s age. Someone can open an issue in the dotnet/runtime repo and implement some of these methods
@andreybiryulin7207
@andreybiryulin7207 Жыл бұрын
You should perf test TryParseIgnoreCase, it doesn't look that fast because switch statement on values internally can be converted to binary search with default comparer on IL level, but switch statement on many bool string.Equals(string, string, StringComparison) will have to be executed sequentially probably. Try to run perf test for TryParseIgnoreCase for last value of large enum, it might be quite slow in my opinion.
@nickchapsas
@nickchapsas Жыл бұрын
With ingoreCase as true, I'm getting a 50% slower result on something that matches exactly (LightGreen), 40% slower on matches case (lightgreen) and a 150% slower result on no match at all (asdf). This is definatley something that people can optmize further but I don't think that ignore case tryparses are that common either. Totally valid point thought I will raise an issue for it.
@benniebees
@benniebees Жыл бұрын
Hmmm. My first guess would be to use a Dictionary for the the TryParse(), and a Dictionary for the ToString(), and then the IsDefined() can use the same dictionary as the one for ToString(). I don't know whether switches are super efficient? If it walks through the options one by one then calculating a hashcode might just be faster.
@nickchapsas
@nickchapsas Жыл бұрын
They are way more efficient than anything runtime unless your enum has thousands of values
@klaesregis7487
@klaesregis7487 Жыл бұрын
That is what I do in my games and programs; although I use a custom BiDictionary class. This allows me to call EnumHelper.Convert(string or enum) and it allows me to iterate over them. The thing is, it is only used when I lazily load new data for lets say a new enemy. So it has to be a bit performant.
@protox4
@protox4 Жыл бұрын
Switch statements on enums past 7 branches are jump tables which are extremely fast. Switch statements on strings are effectively doing the exact same work as a dictionary, but inlined (actually old C# used to build dictionaries). And they were even looking at improving on switches on strings to make it even faster.
@benniebees
@benniebees Жыл бұрын
@@protox4 Ok, so let's say for a moment that a jump table is an array. If your enum has a value for 0, and the next value is 2Billion, (and then has at least 7 variants) will it make a (static) array of that crazy length? =D
@protox4
@protox4 Жыл бұрын
@@benniebees Well, I don't know why my reply got deleted. KZbin is ridiculous... But for that case, the compiler will branch on the single value then jump table on the contiguous values.
@kazepis
@kazepis Жыл бұрын
Thumbs up for the Azure/AWS pun! 😂
@Silentsouls
@Silentsouls Жыл бұрын
Does it help during serialization ? if not it brings a lot of extra generated code that does nothing for me.
@hichaeretaqua
@hichaeretaqua Жыл бұрын
Two thoughts: First, I assume that the API returns a array each time, because the fields of the array can be changed by the caller. Second I'm curious if an implementation using a HashSet rather then a big switch case would be fast with big enums like Color.
@nickchapsas
@nickchapsas Жыл бұрын
For the first one check the pinned comment. For the second one, not it is still significantly (in the context of ns ofc) slower. You need thousands of values in the enum to even see a difference
@Rolandtheking
@Rolandtheking Жыл бұрын
@@nickchapsas I think the underlying implementation of a really big switch is optimised, (e.g. most compilers optimise the IL code). Big switches are rewritten as dictionaries/tree structures/"smart if-else". Not 100pct sure tough. On the video: One of the downsides of these generators might be the amount of code you generate, the thing generates thousands of lines of code, that all will end up in some DLL, all needing to be JIT compiled, loaded into memory, etc. You might not even use all the generated code. Nevertheless, impressive package and a good video! :)
@alim.karim.
@alim.karim. Жыл бұрын
nice to see that bools are used with IsDefined.
@Ranger1230
@Ranger1230 Жыл бұрын
Bummer, I normally go to MDC Minnesota, but my wife is expected to give birth to our daughter then so I'll be missing it this year. :( Hopefully you will come back again in a future year.
@fifty6737
@fifty6737 Жыл бұрын
this library is fast, source generators are a godsend to C#
@josephmoreno9733
@josephmoreno9733 Жыл бұрын
Esta solución debería ser estándar para solucionar los problemas de usar Enums cuando se compila usando NativeAOT con reflexión deshabilitada.
Жыл бұрын
Cool man
@TheAzerue
@TheAzerue Жыл бұрын
Hi Great video. How would you compare it with Smart Eumns. Like where smart enums are preferred.
@nickchapsas
@nickchapsas Жыл бұрын
SmartEnums is more of a DDD style enum approach. This is more of a general take on enums. You can use both, one doesn't replace the other since they serve different purposes
@querywhere6487
@querywhere6487 Жыл бұрын
Am I the only one who thinks, that LightGreen represents the number 69, was not a coincident? :D Enjoy your day!
@asedtf
@asedtf Жыл бұрын
Nick Chapsas: always uses the same seed for his random numbers, that's why he always gets the same two random numbers that don't mean anything. Nice.
@Sodomantis
@Sodomantis Жыл бұрын
Lightgreen... Nice.
@DarraghJones
@DarraghJones Жыл бұрын
With a simple class like this, you can optimise most methods to a dictionary lookup. Note quite as performant as source generators, but not bad either. public static class E where T : struct, Enum { private static readonly Dictionary ValueToName = Enum.GetValues().ToDictionary(x => x, x => x.ToString()); private static readonly Dictionary NameToValue = Enum.GetNames().ToDictionary(x => x, Enum.Parse, StringComparer.InvariantCultureIgnoreCase); public static string ToString(T e) => ValueToName.TryGetValue(e, out var s) ? s : e.ToString(); public static bool IsDefined(T e) => ValueToName.ContainsKey(e); public static bool TryParse(string s, out T v) => NameToValue.TryGetValue(s, out v); }
@antonmartyniuk
@antonmartyniuk Жыл бұрын
nice package
@devbyoli
@devbyoli Жыл бұрын
Are you going to make a video about Dapr - Distributed Application Runtime?
@nickchapsas
@nickchapsas Жыл бұрын
At some point yes
@vmachacek
@vmachacek Жыл бұрын
i see what you did there :D
@andrewiecisa2907
@andrewiecisa2907 Жыл бұрын
Hi Nick, I would be interested in your recommendations for speeding up a startup of a .NET 6 web app. I'm referring to the first execution of a page.
@Lara__
@Lara__ Жыл бұрын
Add a warmup task during startup and then the first call will be fast
@andrewiecisa2907
@andrewiecisa2907 Жыл бұрын
@@Lara__ Thanks for your suggestion, but what exactly should this warmup do? How to apply it to all controllers and views (MVC)? I have tried this approach in past but it wasn't very successful.
@casperhansen826
@casperhansen826 Жыл бұрын
​@@andrewiecisa2907 in Startup make an async task that will make some requests or simply opens the database connection by making a simple select if that is the main reason for the slow first request
@Lara__
@Lara__ Жыл бұрын
@@andrewiecisa2907 You can do it using healthchecks or custom startup tasks. Lots of examples online
@kevinstampe
@kevinstampe Жыл бұрын
Someone submitted an issue+PR for this, minutes after video upload hahaha :D
@MaxHayman
@MaxHayman Жыл бұрын
Is there anything like this to prevent allocation in HasFlag?
@5cover
@5cover Жыл бұрын
Honestly, at this point I think I'll just use classes with a private constructor and static get only properties with an initializer. I can have Name and additional metadata as properties
@MrRobin4444
@MrRobin4444 Жыл бұрын
Interesting package & Good presentation. But i donk like to bloat up the Meta File with big classes. The Enum type is mostly based on reflection in the background, that keeps it small. A source generator sounds simple but could break your neck in big applications. in addition, you get a mix of color extensions and enum.* I dont like the idea to cache the GetNames Array, The Enum strings would live in the memory in that case. 'GetNames()[0] = "luser"' would korrupt the whole thing. Its better to go for an complete different approach like enumeration classes instead of enum types.
@nickchapsas
@nickchapsas Жыл бұрын
There is no meta file, the source generator runs at compile time and adds the classes in your compiled assembly. Regarding the array, you obviously wouldn't expose it as an array and you wouldn't store it as such. You would cache/store it as an ImmutableArray and expose it as an IEnumerable
@lordmetzgermeister
@lordmetzgermeister Жыл бұрын
Enum strings living in the memory isn't a big deal compared to repeated garbage collection of the array every time it's used. The cached array just needs to be immutable.
@MrRobin4444
@MrRobin4444 Жыл бұрын
@@lordmetzgermeister i only know the immutableArray from core applications. not for .net. For immuatbel arrays in .net it is suggetsed to returnin a copy of the Array.
@user-zk5ym9ut1j
@user-zk5ym9ut1j Жыл бұрын
@@lordmetzgermeister I think it shouldn't be array at all. Immutable hashset fits more as values should not repeat.
@MrRobin4444
@MrRobin4444 Жыл бұрын
@@nickchapsas If u compile ur code. A meta file / meta info will be generated for all ur types and methods and member acceses. its normally hidden in ur dll/exe but it exists. U can look into it it with the MSIL Disassembler (Ildasm.exe)
@MattSitton
@MattSitton Жыл бұрын
I use the FastEnum package Instead since for things like unity we don't have source generators yet
@saniel2748
@saniel2748 Жыл бұрын
Actually we do
@CheesySteve
@CheesySteve Жыл бұрын
LightGreen is 69. Example failure is 420. Nice.
@bjdubb
@bjdubb Жыл бұрын
I would love to come meet you at NDC Sydney but the 1-Day pass is $1,600 AUD ($1,100USD) Unfortunately I wont be able to make it, but i hope you have an awesome time man ❤️
@nickchapsas
@nickchapsas Жыл бұрын
The tickets are always paid by the companies that individuals work for so you can speak with your manager and see if you can expense the trip. First time in Australia so to say that I'm excited is an understatement
@bjdubb
@bjdubb Жыл бұрын
@@nickchapsas Unfortunately I am not yet working for a company. Im only 18 and still looking for my breakthrough into the software industry. Hopefully you’ll be at ones in years to come and ill be able to meet you. For now, ill just keep binging your videos 😆
@tera.
@tera. Жыл бұрын
I benchmarked the TryParse method when ignoreCase is true, it seems to be overall worse than default implementation. Like, extremely worse (10x+) when the value is numeric, and about 2x worse otherwise.
@nickchapsas
@nickchapsas Жыл бұрын
I am not getting the same numbers. With ingoreCase as true, I'm getting a 50% slower result on something that matches exactly (LightGreen), 40% slower on matches case (lightgreen) and a 150% slower result on no match at all (asdf). This is definatley something that people can optmize further but I don't think that ignore case tryparses are that common either. Totally valid point thought I will raise an issue for it.
@KimichisxD
@KimichisxD Жыл бұрын
Can I ask why are you using "var" all the time? Is it more performant? Or is it just because it is faster to explain stuff in videos. Thank you! :)
@Dippps
@Dippps Жыл бұрын
Its not more or less performant. var is just short.
@ronsijm
@ronsijm Жыл бұрын
var makes it easier to refactor things. Imagine you have _var output = controller.Result();_ Initially your controller might just be returning a _string_ , but later on you want to change the output of your controller to an _ActionResult_ ... if you wouldn't have used _var output =_ but _string output =_ you'll also have to go fix that everywhere you're invoking the controller
@nedgrady9301
@nedgrady9301 Жыл бұрын
That's the style you'll see most examples on the Microsoft docs using, which often stick with the wider population. docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions#implicitly-typed-local-variables
@georget10i
@georget10i Жыл бұрын
Can I make a confession? I absolutely do not care or worry about optimizations. I am your basic grey mouse developer. I do not work with anything that is mission critical down to nano seconds. I only concentrate on one thing: Clarity of code. Use the basics, make it easily readable and understandable. Follow a few well established principles and no need for over complicated new solutions from that latest trendy blog article (I am really not a fan of the latest blog article developers. And I also don't like overreliance on too many Nuget packages). The rest... I figure C# is a tool, it's the tool maker's job to give me a "hammer" that won't fall apart when I beat the nail with it. By the time it reaches someone like me, it should be "good enough". Don't get me wrong, this is not a criticism of you at all, Nick. I am very thankful for your videos and appreciate them, keep doing them. It's good to have video like this to get a look under the curtains sometimes. I am just sharing my thoughts in case someone out there is getting overwhelmed with all the knowledge and all the things they need to know. Developers like Nick are exceptions. So don't worry! You'll be fine. Just do the basics and do them well.
@gordug
@gordug Жыл бұрын
You always say it's only a few nano seconds but when you're paying for processor time it will eventually add up.
@lordicemaniac
@lordicemaniac Жыл бұрын
did I understood it correctly, that you should not create new array each time if its the same array every time, but rather have one created and cast it?
@nickchapsas
@nickchapsas Жыл бұрын
In this specific scenario, because it's all immutable data, the array can be cached in an ImmutableArray and exposed as a IEnumerable to the user to consume as they want.
@mabakay
@mabakay Жыл бұрын
Damn! Until now I used just HashSet or Dictionary with few additional lines of code.
@manasseth4991
@manasseth4991 Жыл бұрын
I read your thumbnail as"Let's fix the problem with EMUS" and thought you were Australian.
@nickchapsas
@nickchapsas Жыл бұрын
Tbf anything that can take 5 bullets and walk away is better than C# Enums
@devbyoli
@devbyoli Жыл бұрын
What about using SmartEnum ?
@MattSitton
@MattSitton Жыл бұрын
I use FastEnum
@nickchapsas
@nickchapsas Жыл бұрын
SmartEnum serves a different purpose. It’s more of a DDD package. This one is completely general
@protox4
@protox4 Жыл бұрын
Is it able to handle flags enums?
@nickchapsas
@nickchapsas Жыл бұрын
There are HasFlags methods, yes
@protox4
@protox4 Жыл бұрын
@@nickchapsas I mean how does it handle the strings of flags enums? If it's still allocation free, I imagine that generated code could get huge for every combination.
@EdubSi
@EdubSi Жыл бұрын
Not sure if it is a good idea to cache a mutable Array.
@nickchapsas
@nickchapsas Жыл бұрын
You can prevent the user from mutating it by storing two arrays and copying the original into the one you return, making it faster and preventing the allocation and the mutability concerns. Check the pinned
@Dimich1993
@Dimich1993 Жыл бұрын
I can't believe there are only 2 random numbers!
@user-th2if1dw3e
@user-th2if1dw3e Жыл бұрын
every time I see a 69 I smile, every time I see a hidden 69 I laugh out loud : >
@leonardoformaggi7614
@leonardoformaggi7614 Жыл бұрын
I have a package that has a similar name and does similar things. If it appeared on the video I would've had a heart attack or something lol
@leonardoformaggi7614
@leonardoformaggi7614 Жыл бұрын
Also my method for "GetValues" uses a private static to cache the array :D
@KibbleWhite
@KibbleWhite Жыл бұрын
Unless you're colour blind.... whatever.
@austinkispotta3561
@austinkispotta3561 Жыл бұрын
Lmao me too. I was eating while watching and almost spit out the food.
@AniProGuy
@AniProGuy Жыл бұрын
What is gonna happen if you refactor the name of the enum? ^^
@phusicus_404
@phusicus_404 Жыл бұрын
This looks as an ultimate boilerplate Also, it's just a switch, so why C# std enum is that lingering?!
@MulleDK19
@MulleDK19 Жыл бұрын
9:07 Why would it be slower with 20,000 items? It's a switch and your enum is sequential. It's O(1).
@nickchapsas
@nickchapsas Жыл бұрын
That is true, sequential enums will generate a jmp JIT ASM instruction so they will be O(1) but non sequential ones are not if I remember correctly. I should have been explicit in the video
@billy65bob
@billy65bob Жыл бұрын
It appears this doesn't deal well with flag enums.
@lyrapuff7502
@lyrapuff7502 Жыл бұрын
And I keep missing rust enums when using C# xd
@wudewang9947
@wudewang9947 8 ай бұрын
yeah, code is data, in source generator
@Omego2K
@Omego2K Жыл бұрын
I notice you're reusing specific numbers in your video
@nickchapsas
@nickchapsas Жыл бұрын
You're wrong, they are random
@Omego2K
@Omego2K Жыл бұрын
@@nickchapsas from a set of two
@ChristopherSalisburySalz
@ChristopherSalisburySalz Жыл бұрын
Have you ever worked as a salesman?
@NicholasLayton
@NicholasLayton Жыл бұрын
You really used 69 and 420
@FR-bq3jo
@FR-bq3jo Жыл бұрын
Hey bro, i love your videos, but i have something to beg you, i have a little bit difficulty in understand your accent, can you provide some legends in english?
@astralpowers
@astralpowers Жыл бұрын
Couldn't this be done by the JIT? I like the idea but it produces a lot of code.
@Andrei-gt7pw
@Andrei-gt7pw Жыл бұрын
Would be nice if lowering would do this instead.
@antonkarpov9841
@antonkarpov9841 Жыл бұрын
cOlors
@user-zk5ym9ut1j
@user-zk5ym9ut1j Жыл бұрын
I almost choked when I've seen 1000+ references to Enum class after source generator. It basically renders Intellisense bloated with stuff that should be hidden. Very bad.
@nickchapsas
@nickchapsas Жыл бұрын
It doesn't affect intellisense at all. The references are contained to each enum value so you never have more than one
@user-zk5ym9ut1j
@user-zk5ym9ut1j Жыл бұрын
@@nickchapsas I'm speaking about 6:17 on video From 5 usages of enum to 1423, and all lead to source generated code What are u talking about?
@MrNickP
@MrNickP Жыл бұрын
Leave micro-optimizations to the dotnet team. The average developer will spend more time watching this video than will be saved over the lifetime of any application implementing it. You have to ask yourself if the performance increase is enough to justify requiring a third party package (and potential security issues it represents) that introduces non-standard alternative methods that increase complexity for new team members to save 20 nanoseconds? .00000002 seconds.
@nickchapsas
@nickchapsas Жыл бұрын
For the software I write, it does. For many other people, it won’t. The video isn’t for everyone to apply but it is worth knowing. When the time comes to optimise you need to know what to optimise. This is also not about the speed of execution but primarily for the memory. When I’m dealing with 50k request per second (which I do), and I have 4 of those calls per request then that means 50000*4*24=4,800,000 bytes of memory I have to garbage collect per second. Performance is contextual, but optimisations like this apply to a lot of people.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 247 М.
The fastest way to cast objects in C# is not so obvious
11:10
Nick Chapsas
Рет қаралды 72 М.
Buy Feastables, Win Unlimited Money
00:51
MrBeast 2
Рет қаралды 98 МЛН
ХОТЯ БЫ КИНОДА 2 - официальный фильм
1:35:34
ХОТЯ БЫ В КИНО
Рет қаралды 1,2 МЛН
Don't eat centipede 🪱😂
00:19
Nadir Sailov
Рет қаралды 21 МЛН
GUIDs and UUIDs are cool, but this is cooler
15:55
Nick Chapsas
Рет қаралды 175 М.
Why all your classes should be sealed by default in C#
11:43
Nick Chapsas
Рет қаралды 91 М.
"Stop Wasting Memory on Strings in C#!" | Code Cop #016
9:20
Nick Chapsas
Рет қаралды 66 М.
Why .NET's memory cache is kinda flawed
14:13
Nick Chapsas
Рет қаралды 54 М.
One Trick To Improve EF Core Performance Using Query Splitting
9:52
Milan Jovanović
Рет қаралды 32 М.
How IEnumerable can kill your performance in C#
11:02
Nick Chapsas
Рет қаралды 111 М.
The NEW caching you should be using in .NET 7
18:17
Nick Chapsas
Рет қаралды 75 М.
You Completely Misunderstand How Strings Work in C#
8:46
Nick Chapsas
Рет қаралды 43 М.
Buy Feastables, Win Unlimited Money
00:51
MrBeast 2
Рет қаралды 98 МЛН