"Stop Wasting Memory on Strings in C#!" | Code Cop

Sdílet
Vložit
  • čas přidán 3. 04. 2024
  • Use code CLEAN15 and get 15% off the brand new "From Zero to Hero: Writing Clean Code with C#" course on Dometrain: dometrain.com/course/from-zer...
    Become a Patreon and get special perks: / nickchapsas
    Hello, everybody, I'm Nick, and in this video I will take a look at really bad advice related to string allocations in C#. Not only is this advice really bad but it's worse because of context.
    Workshops: bit.ly/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: github.com/Elfocrash
    Follow me on Twitter: / nickchapsas
    Connect on LinkedIn: / nick-chapsas
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 98

  • @SkyyySi
    @SkyyySi Před měsícem +185

    Every "clean code" guidebook should start with a chapter on how to delete your LinkedIn account

    • @DotNetDemon83
      @DotNetDemon83 Před měsícem +1

      I am printing this out and pasting on my office door

    • @7th_CAV_Trooper
      @7th_CAV_Trooper Před měsícem +11

      rule 1: delete your linked in account
      rule 2: never take advice from an "engineer" wielding an Apple product

    • @suic86
      @suic86 Před měsícem

      ... or don't even create one.

  • @marcusmajarra
    @marcusmajarra Před měsícem +81

    That doesn't seem like an April Fool's prank. An actual April Fool's prank would either be completely over the top or at least progressively become more and more obviously ridiculous. It's more likely that this person got called out and used April Fool's as an excuse after the fact.

    • @ChristofferLund
      @ChristofferLund Před měsícem +9

      100%. Unless he can PROVE it was an April fools joke he just got caught

  • @mk72v2oq
    @mk72v2oq Před měsícem +61

    String concatenation/interpolation will be resolved in compile time, if strings are const. It is called constant folding.
    I.e. such code
    const string a = "a";
    const string b = "b";
    const string c = $"{a} and {b}";
    const string d = $"{a} and {b}";
    Console.WriteLine(ReferenceEquals(c, d));
    will print "True".

    • @Silverflame1
      @Silverflame1 Před měsícem

      That's true. In java it's called compile-time concatenation and runtime concatenation. I always found it a bit weird but once I properly learned it it made a lot of sense.

  • @klocugh12
    @klocugh12 Před měsícem +77

    Intern was the one who actually probably wrote that advice.

  • @Matlauk
    @Matlauk Před měsícem +28

    THis is why hate the removal of dislike/down vote buttons accross the web. It makes it look like this other terrible information is good when it's really ass.

  • @JonathanPeel
    @JonathanPeel Před měsícem +36

    Do you know what I want to see someone try....
    Do you remember when we all discovered that on googles homepage only one image file downloaded, and CSS would be use to crop sprites out and use those for all images displayed?
    Lets do that with strings in C#.
    Lets declare one massive string (that contains any possible character sequence we might need in our application).
    And then whenever we need something we can use Span to grab just the portion we need.
    😆😆😆

    • @guiorgy
      @guiorgy Před měsícem +2

      Sure, let's do some maths just in case. Assuming our strings only have ASCII alphanumerals (letters and numbers), that's 62 characters (26+26+10), and our strings are exactly 10 characters in size, and a character size in memory is a byte (it's 2, but ignore that for now), the number of bytes needed to store all those combinations would be 62^10, or 8.39x10^17, which is equal to 781,658 TeraBytes... On second thought, let's not do that 😅
      And if what you want is to only store strings that you know your app is using instead of all combinations, then that's EXACTLY what string Intern does

    • @fusedqyou
      @fusedqyou Před měsícem +4

      Just specify the whole list of possible UTF-8 characters and pick from the string when building your string. Easy!

    • @7th_CAV_Trooper
      @7th_CAV_Trooper Před měsícem +1

      That massive string idea is pretty good. It's called the heap.

    • @braddabug8598
      @braddabug8598 Před měsícem +3

      Sounds like pi compression. You calculate pi to however many digits you need before you find a series of numbers that matches whatever data you're trying to compress. Then you just store the offset and length. The compression ratio is pretty good. Compression and decompression is a little resource intensive though.

  • @marklord7614
    @marklord7614 Před měsícem +9

    Why did String.Intern break up with its garbage collector?
    Because every time it tried to be efficient with memory, the garbage collector said, "I don't see any future in this relationship. You keep holding onto things from the past!"

  • @VeNoM0619
    @VeNoM0619 Před měsícem +3

    I've used string.Intern and made a ListIntern class for a deserializer of a mongoDB array.
    ONLY because the string values were common, but with some custom flexibility. Like "categories of x" type stuff. Basically if you ran a distinct on 100k rows, you would get less than 100 unique values, type stuff.
    My advice is only use intern when you see common strings live in memory for over several minutes, that aren't capable of being in just an enum (because they are dynamic/custom)
    I've also made a custom object.intern type class, because it allows me to completely reset the intern memory, or group chunks/categories. Think I've only used it on strings though, cant recall.

  • @oguzhan0Kahyaoglu
    @oguzhan0Kahyaoglu Před měsícem +3

    Hey Nick, in my 12 yr .net swe life, I only used once the intern method, to be able to lock a method by a value of a string. If you lock using the string itself, it does object comparison and it does not actually lock as the string value was coming from the request. Then we needed to intern it...

  • @AkariTheImmortal
    @AkariTheImmortal Před měsícem +7

    I didn't know about string.Intern. It's definitely good to know that this happens automatically from the compiler. I therefore also don't see, why I would ever use it manually in my own projects, since it's already happening where it makes sense. But just knowing that this happens is good, I think.

    • @reikooters
      @reikooters Před měsícem

      Nick has made a video on this already which you can check out for more examples

    • @AkariTheImmortal
      @AkariTheImmortal Před měsícem

      huh, thanks. I will check that out. I have found this channel only recently, so there is probably a lot that I haven't seen yet.

    • @TehGM
      @TehGM Před měsícem +2

      It might be useful in very VERY specific scenarios. For example when the strings are not necessarily known at compile time (or are known, but new instances come from deserialization for example), the possible set is limited and relatively small, you trust the source, and strings will be long lived (like long memory cache etc). Yes, all these conditions are an AND, combined.
      I actually did use interning in my project recently, although doing this as means for trying to find the cause of constantly increasing memory use (memory leaks gonna be the death of me).
      It is a tool, and it exists to be used - however if you know what you're doing and are sure you need it. This is definitely a rare case that you'll need manual string interning. In VAST MAJORITY of cases you do NOT need to even worry about it.

    • @c.Orange
      @c.Orange Před měsícem

      @@TehGM lets say i have a json with a branch for "colors" at the top, which contains a "red": "255 0 0 255", and then "elements" below it, which contains many other branches for different elements, such as "mainmenu" and all that, which contains all the elements and configurations for those, and those elements have colors set to them, such as "fgcolor" for a button which uses the "red" (to give an idea of why repeat values happen in this case)
      so if i got this right, i could intern the values from the element color configurations and other repeat cases in branches in deserialization to optimize it.
      (to make sure i understood this correct, found your mention of this interesting in stuff i may need it in as im dealing with something like this and there are tons of repeat values trough that, ill prolly benchmark this later)
      not that ill need to optimize though. but i could funky it up to make things nicer. generally see if ill add to this as a standard to future stuff if there's no harm in it when done right.

    • @TehGM
      @TehGM Před měsícem

      @@c.Orange I'd shy away from interning values, as values by nature can be very different. Keys on the other hand might make sense.
      I specifically use it for character stat IDs - all stats come from API, so they might change once game updates, but they're still finite and really frequent. So interning these might make sense.
      However, you say you don't need to optimize that yet. In that case, skip manual interning altogether. Only worry about it when you actually see memory issues, and believe this might be the cause. Don't optimize prematurely.

  • @BrunoSirianni
    @BrunoSirianni Před měsícem +4

    I agree, very bad advise! I would add that the compiler does also more magic if things are correctly declared!
    For example doing string concatenation of only consts and literals also the result is an intern (because it's still const).
    const string hello = "hello";
    const string world = "world";
    var all = "hello world";
    var a = hello + " " + world;
    var b = $"{hello} {world}";
    Debug.Assert(ReferenceEquals(all, a), "not intern");
    Debug.Assert(ReferenceEquals(a, b), "not intern");

  • @RoyBarina
    @RoyBarina Před měsícem +9

    Wait, is that mean HTML isn't the best programming language ever created??

  • @7th_CAV_Trooper
    @7th_CAV_Trooper Před měsícem +4

    You can save memory by reducing the font size. Same trick can be used to lighten your laptop.

    • @MattWanchap
      @MattWanchap Před měsícem +1

      Now THAT would have been a good April fool's joke!

    • @HackerUC
      @HackerUC Před měsícem

      you can also save memory by switching to light mode in VS / VS Code

  • @bogdan.p
    @bogdan.p Před měsícem +3

    I think the author just used the excuse of the april fool joke when he saw people pointing out he's wrong in the comments.

  • @jongeduard
    @jongeduard Před měsícem +1

    Maybe it's good to note that composed strings, either by concatenation or interpolation, can also be completely evaluated compile time and therefore interned.
    This happens in the cases where all parts which compose the string are either literals or const declared identifiers.
    This type of string composition also comes with absolutely zero runtime overhead, and decompiled code will just show the whole thing joined together.

  • @user-mn1pw5hp2y
    @user-mn1pw5hp2y Před měsícem

    Thanks Nick ! Keep it real !

  • @haxi52
    @haxi52 Před měsícem +1

    It bothers me how much emphasis on [micro] performance people have with C#. If you __really__ need it (and you probably don't), then go use C++. C# is really fast on its own without much special attention. Its far more important to focus on readability and maintainability.

  • @F1nalspace
    @F1nalspace Před měsícem

    100% agree. Dont use string.intern manually unless you a have specific use-case for that.
    Btw i bought that clean code course on dometrain and are neither impressed nor disappointed. It is a good course for new programmers and i like it that it does not follow the "clean code" book from uncle bob. It uses good concepts, but if you are an experienced programmer you most likely know them already and may already use them. Also one important concept is missing -> Clean code on class/library/application level! You should add them as well, simply following the SOLID principles and decrease coupling and increase cohesion, but only when it makes sense. Oh and i am not a fan of introducing libraries into the mix, when normal C#/.NET is totally sufficient (e.g. Guard Clauses).

  • @petterhoel
    @petterhoel Před měsícem

    Have you done any tuning to your Rider setup? It it always so snappy. If so I would love a How to set up Rider walkthrough

  • @Philippe42460
    @Philippe42460 Před měsícem

    Hahaha! I already saw the corresponding tip on linkedin and I told to myself : oh well, I know what will be the next episode of code cop...
    And it looks like I was right! 🙃

  • @BackwardsDaveTV
    @BackwardsDaveTV Před měsícem

    @5:50 if you declared the hello and world variables as const instead, string a and b would then contain the same reference, right?

  • @KingOfBlades27
    @KingOfBlades27 Před měsícem +1

    Definitely agreeing with you that making april fools jokes like this is just extremely dumb. For sure someone actually thought this was real advice and will use it somewhere.

  • @QwDragon
    @QwDragon Před měsícem

    As I know Roslyn (I mean code of the compiler itself, not the code it compiles) interns all the strings to gain large perf boost from always comparing strings by reference and never by value. Is that true or I misread smth several years ago?

  • @JustinLampe
    @JustinLampe Před měsícem +1

    I saw the same post on X, and I wondered if it would make sense to mention you there. However, I took on the role of "Code Cop" and explained why this advice doesn't make sense.

  • @winchester2581
    @winchester2581 Před měsícem +2

    ❌Stop using strings!
    ✅Instead, use char arrays!

    • @7th_CAV_Trooper
      @7th_CAV_Trooper Před měsícem +1

      just malloc a void pointer and make a mental note on the type and size.

  • @joshpatton757
    @joshpatton757 Před 25 dny

    I feel like there is a decent sized subset of coders out there who don't actually understand that the compiler optimizes for you - more than once I've found code or inherited projects where the previous person was spending significant work to try to hand-optimize the code and wound up producing identical or near identical results post-compilation.
    It's like there is a tendency to assume that what you wrote is going to be strictly translated one for one to IL.

  • @qub1n
    @qub1n Před měsícem +1

    Maybe they post it on LinkedIn by intention and wait for senior developer to noticed that it is wrong.

  • @HHHamiller
    @HHHamiller Před měsícem

    I think the StringBuilder class deserves mentioning. Isn't that the recommended way if you have to combine strings? I don't know how it compares in memory usage and performance.

    • @ErazerPT
      @ErazerPT Před měsícem

      Careful. You're falling precisely into the dogmatic fallacy these videos fight. Advice that, right or wrong, doesn't provide full context. SB is NOT free. It has to be brought into existence, an initial alloc must be made as it needs memory to work with, and then you MIGHT reap benefits. If you "macro" your code substituting every a+b with a StringBuilder, you're going to DEGRADE your performance. The key point is understanding what StringBuilder was made for. It was never to do a+b, they'd have changed String if that was the case. It was for "building content in a string form in an iterative manner". Something like out=string.Empty; foreach(string word in wordlist){ out+=word; }.
      Now the question becomes "when does a+b fall behind StringBuilder?". And the answer as usual is "Benchmark it" :)
      p.s. you can apply this to anything of the sort, say for example LINQ. LINQ is NOT free, and depending on your use case, you might be better of with a simple for loop.

  • @Esgarpen
    @Esgarpen Před měsícem +2

    *nervous const string a = "Hello world" noises*

  • @talwald1680
    @talwald1680 Před měsícem

    The main benefit of using intern is actually to save on equality checks on the same objects.
    The memory saving is a bonus but probably isn't worth the overhead.

  • @tonystoynev7969
    @tonystoynev7969 Před měsícem +1

    This time I recognised the author of the post because I am following him and I saw the post recently

  • @MasterJaffer
    @MasterJaffer Před měsícem +1

    Everything stupid enough can retroactively be an April fools joke. "Lol jk guyssss"

  • @danielprows6416
    @danielprows6416 Před měsícem

    can't wait until copilot gets inadvertently trained on april fools day jokes

  • @dmitrykaznacheev5929
    @dmitrykaznacheev5929 Před měsícem

    Also need a string for intern, means memory already allocated

  • @Velociapcior
    @Velociapcior Před měsícem

    are there any comments under those posts? Can you show them at the end? Anonymized of course

  • @alexclark6777
    @alexclark6777 Před měsícem

    Sort of makes me think this wasn't an April Fool's joke until the OP got called out for it and it became "just a prank, bro!"

  • @dariogriffo
    @dariogriffo Před měsícem +11

    The sad thing is that the same day this post was created the author got a MVP award from Microsoft. You can tell that Microsoft gives MVP as candy to kids.

    • @dariogriffo
      @dariogriffo Před měsícem +2

      the post was deleted :P

    • @thecodeman_
      @thecodeman_ Před měsícem +1

      @@dariogriffo The Good old Griffo 😂 If you need a complete post with all the comments, I saved it for guys like you, ping me, will send it to you. :) Of course, I deleted the post, it's a joke. And yes, I could delete Nick's comment, but I know what I did on purpose. And I knew someone would tag him. I could have deleted the comment, but there's no need for you to. In the comment, I even allowed Nick to mention and use my post in the video because otherwise there could be problems. :)
      Ah yes, the famous MVP award. Well, if you have been told, it is not actually given for someone who posted 2,3 posts there, instead, for contributions all over the internet going back months and years. And since you are such a faithful follower of mine (thank you! :D), you know that where I am, I have not been since yesterday. One "joke" post (I still think it's sarcastic - my followers didn't take it for granted) will certainly not undo all the good I've done so far. Enjoy! :D

    • @dariogriffo
      @dariogriffo Před měsícem

      @@thecodeman_ I'm 41, that's not old...

  • @qub1n
    @qub1n Před měsícem

    I use string.intern for string which repeats thousand times and are created dynamically. The qain is hardly measurable.

  • @eyefivefive
    @eyefivefive Před měsícem +1

    Don't try to outsmart the compiler.

  • @zbaktube
    @zbaktube Před měsícem

    Yes, there is place for potentially harmful jokes like ranking every programming language 🙂 About this advice, I would make mandatory to read Clr via C# for every C# developer. This should be so obvious.
    I was thinking doing an April's fool joke myself as well: that Microsoft solved it's longest running bug and now we can make lock() on a type itself, but I chickened out 🙂
    I think the real problem is developing against clr without knowing how it works.

  • @mehdibiny2257
    @mehdibiny2257 Před měsícem

    Good contant. Im agree with u

  • @enriquejhc01
    @enriquejhc01 Před měsícem +1

    And then the AI uses the post to give advice.

  • @AhmadElkhouly
    @AhmadElkhouly Před měsícem

    Don't listen to advices (including this)
    Just do things your usual way until you find out there is a problem that needs an advanced or unusual way to solve.

  • @nitrous1001
    @nitrous1001 Před měsícem

    The real way to have zero heap-allocated strings is to stack allocate a span of characters. Good luck finding APIs that don't take strings though!

  • @mgbrown09
    @mgbrown09 Před měsícem

    This throws up the question: How do you decide when to use a string literal v a resource file string?

  • @yannolaf
    @yannolaf Před měsícem

    Are there cases where it makes sense to use string.Intern()?

    • @zachemny
      @zachemny Před měsícem +2

      When you load into memory large chunks of data (i.e. files) that contain lots of identical strings (keys, identifiers, tags, keywords and so on). And you intend to keep and use these strings (especially compare them) for a long period of time.

    • @billy65bob
      @billy65bob Před měsícem +2

      There are, but generally speaking, 99.99% of what you could conceivably want interned is already interned anyway.
      I'd generally only recommend using it for Keys you don't know ahead of time, and only from trusted sources at that.
      If you're reading data with a lot of repeating Values, consider the High Performance Community Toolkit's StringPool instead.

  • @Shazam999
    @Shazam999 Před měsícem +3

    This is why i just stream binary to the user.

    • @MattWanchap
      @MattWanchap Před měsícem

      That would have been a good April fool's day joke. Improve your API performance by avoiding slow, inefficient JSON serialization and simply pass raw binary instead! Here's a benchmark showing how much more efficient it is, just don't try to read the output

  • @ronsijm
    @ronsijm Před měsícem

    Protip: Save memory on strings: stop respecting immutability on strings. If you have one string, you can create an unsafe block, create a pointer to a string, and just use the same string over and over again. You pretty much only ever need 1 string instance ever, if you keep changing that same string forever

  • @andywest5773
    @andywest5773 Před měsícem

    My guess is their next "tip" would be to concatenate string literals with StringBuilder.

  • @kristofbe1
    @kristofbe1 Před měsícem +1

    I think this wasn't an April fool's joke to begin with. I think the person who posted this got a lot of critique and decided to try and save face by saying it an joke afterwards.

    • @chuercowrench
      @chuercowrench Před měsícem +1

      this makes sense. Jokes generally have humor.

  • @KNHSynths
    @KNHSynths Před měsícem

    Why using "intern" when you can 1/ use const 2/ think "DRY" and never repeat literals...

  • @PaulPendor
    @PaulPendor Před měsícem

    I’m sorely tempted to write one of these horrific LinkedIn posts, but use the capital letters of each sentence to spell out “code cop” or “call Nick” 😂

  • @VanDameDev
    @VanDameDev Před měsícem +1

    Unpaid String Interns are the worst!

  • @margosdesarian
    @margosdesarian Před měsícem

    I follow you and only you Nick

  • @dmitrychelnokov8430
    @dmitrychelnokov8430 Před měsícem

    I used string.Intern in 2007)))

  • @CaltorStorm
    @CaltorStorm Před měsícem

    If you're tying to save memory in C# then I would say that you've already gone wrong

  • @TECHN01200
    @TECHN01200 Před 10 dny

    Linkedin does need a dislike button. X has the same problem.

  • @MumleDK
    @MumleDK Před měsícem +1

    It's just a prank, bruhh

  • @bogdanzarzycki9885
    @bogdanzarzycki9885 Před měsícem +2

    Such posts aren't deleted after april 1. ...

  • @saberint
    @saberint Před měsícem +1

    I’m just going to keep using string because I am lazy and can’t be bothered typing more to knacker my code

  • @foonlam7134
    @foonlam7134 Před měsícem +1

    I don't like April fool jokes. Verbal or practical jokes are often harmful coz many people don't think of the effect it has on others. Then when something bad happens they say "Oh I didn't mean it". Well it's too late by then. Use your brain even if you have very little of it.

  • @zethoun
    @zethoun Před měsícem

    why on earth do you want to have 2 identical strings declared in your code? I don't get it...

  • @thecodeman_
    @thecodeman_ Před měsícem +2

    Hi Nick!
    Thank you for commenting on the post and thank you for posting the video, which I myself agreed with in advance.
    As you realized yourself, as it was written in the comment (not sure why are u saying it's not, but ok :D ), this was an April Fool's joke.
    After a few hours, the post itself was updated to make it even more obvious.
    In the end, the post was deleted, of course.
    What I really liked, which you could see for yourself, was that people shouted at me in the comments that what I wrote was not true - which means that people already knew a lot about it, and even if they didn't, they saw more comments that confirm it.
    At the end of the day, the "advice" is pretty basic.
    I hope the video gets a good response and you get a good conversion! :D
    Enjoy the sunny day!

    • @bogdan.p
      @bogdan.p Před měsícem +1

      When you posted this, there was no hint about it being a joke, not even in the comments. I saw your post a few hours after it being posted. And you did not respond to people proving you wrong either.

    • @thecodeman_
      @thecodeman_ Před měsícem +2

      @@bogdan.p Wrong. In the first comment "Be sure to repost the post = help others to learn something new." on the bottom I wrote exactly that. :)

    • @Basement-Science
      @Basement-Science Před měsícem

      @@thecodeman_ You're about as funny as a cancer diagnosis. I suggest you stop trying to post jokes on the internet.