What is Span in C# and why you should be using it

Sdílet
Vložit
  • čas přidán 12. 07. 2021
  • Become a Patreon and get source code access: / nickchapsas
    Check out my courses: dometrain.com
    Hello everybody I'm Nick and in this video I am going to talk about Span of T in C#. Span was introduced in C# and .NET alongside a series of optimisations all the way back in .NET 2.1 and it has come to my attention that it is really confusing to understand if you just read the documentation for it. In this video I will break it down for you and help you understand exactly what it is, how it works and how you can use it in your applications today!
    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 #span

Komentáře • 274

  • @nickchapsas
    @nickchapsas  Před 2 lety +239

    Hello everybody. As some people have already pointed out, after 13:50, when I'm returning a ReadOnlySpan, the ToString() on line 21 should be removed. I didn't notice because of the implicit operator. If you leave the ToString() in then you still allocate the string you return.
    - Keep coding

    • @lipatovsa7
      @lipatovsa7 Před 2 lety +2

      Great video. But where could I check source code?

    • @nickchapsas
      @nickchapsas  Před 2 lety +3

      @@lipatovsa7 The source code is available to my Patreons

    • @PeterManger
      @PeterManger Před 2 lety +6

      Thought you were just testing if we paid attention!

    • @roflex2
      @roflex2 Před 2 lety +1

      @@nickchapsas What would be the benefit/differences in using method(in string text) method(ref string text) ?

    • @nickchapsas
      @nickchapsas  Před 2 lety +3

      @@roflex2 strings are immutable in C#. Even if you pass down explicitly by reference your can't change the value of the string. You just point to a new string reference type

  • @GeraldOSteen
    @GeraldOSteen Před 2 lety +277

    I'm a systems developer and primarily work with low-level languages like ASM, C, C++, etc., so I don't have a lot of experience on the intricate details of optimizations for managed languages. Explanations like these are invaluable and I find them immeasurably useful so I thank you very much for this.

    • @KayOScode
      @KayOScode Před 2 lety +6

      Yeah typically managed languages have to add complex features to get the same speeds we get using lower level languages. Its a big trade off in my opinion. In those languages you usually either have to swallow performance penalties or readability penalties. In languages like c++, using a pointer isnt going to confuse anyone. So really I prefer those languages, but it is cool to learn the intricacies of these languages. In particular because I use it for a my job

    • @minciNashu
      @minciNashu Před 2 lety +1

      C++ also introduced similar concepts as standard, and before that there were 3rd party libraries providing some kind of span. See std::string_view and std::span

    • @KayOScode
      @KayOScode Před 2 lety

      @@minciNashu arent those features kind of just bloat though. We have void* and thats all we really need

    • @mikicerise6250
      @mikicerise6250 Před 2 lety +6

      My first thought was, I mean, great, but why do I get the impression that C# has a lot of tricks for solving problems caused by C# in the first place? ;) Why not just have a span method on the string that returns a readonly reference to a section of the string?

  • @chrisd961
    @chrisd961 Před 2 lety +82

    I'm so impressed by these explanations. Honestly, the best thing to happen for a junior dev, is to find your channel. Great explanations, very helpful videos with in-depth knowledge and analysis. Thank you, please keep doing them!!

  • @sasukesarutobi3862
    @sasukesarutobi3862 Před 2 lety +61

    Span is a really under-rated feature, not just for performance, but also my favourite pun in C# - TimeSpan

    • @RichardNobel
      @RichardNobel Před 2 lety +7

      Spantastic pun 😉

    • @RichardNobel
      @RichardNobel Před 2 lety +11

      If you have a dog... it's probably a Spaniel ? 🐕

    • @jeffwilson8246
      @jeffwilson8246 Před 2 lety

      Lately the news has been so dull I've tuned into Cspan

    • @tuck1726
      @tuck1726 Před 2 lety +1

      @@jeffwilson8246 This whole thread makes as much sense as watching C while only wearing a .
      I don't get the OP. I understand span and TimeSpan, but I don't see the pun. I am the dummy cause 40+ people saw it. Guess I need to get out of my static internal scope of thought.

  • @evolvedant
    @evolvedant Před 2 lety +48

    When I first watched Microsoft themselves explain Span, I was lost and confused. They have a knack for making something sound way more convoluted and complex than needed when they explain new concepts. This video made it all click instantly. Thank you very much, I can't wait to start using Span in my own work.

    • @Faygris
      @Faygris Před rokem +6

      The same is true for their documentation

    • @mrx10001
      @mrx10001 Před rokem +6

      ye microsoft love overcomplicating every single one of their examples.....they need to hire people to teach them to keep things simple. Especially for their documentation.

  • @Manlyman789
    @Manlyman789 Před 2 lety +23

    I love these types of videos that explain the standard classes in the framework that help you write more efficent code. These are the types of things I don't stumble upon when researching how to solve a problem. I would love to see more videos like these!

  • @RichardNobel
    @RichardNobel Před 2 lety +7

    Great explanation, Nick, yet again! Thank you for taking the time, in your very informative videos, to show us what's happening "behind the scenes". On the heap, stack, etc. 🙏🏻

  • @jackkendall6420
    @jackkendall6420 Před 2 lety +5

    Great video. This is a topic I've been half-aware of for a while, but seeing it in context helps a lot.

  • @AndreMauricio4
    @AndreMauricio4 Před 2 lety +1

    hey Nick, I have been watching your videos for a while. Just want to thank you so much for the learnings I got from them. You cannot imagine how helpful you are to people like me. I am using these learnings in a software solution I am developing myself already for a year. Again, thanks!!!
    Andre from Portugal

  • @snuffsix9598
    @snuffsix9598 Před 2 lety

    Your video's are awesome. I very much appreciate the technical in-depth explanations of them. Thanks a ton!

  • @JoeEnos
    @JoeEnos Před 2 lety +1

    As usual, you explain the nuts and bolts, the theory, and the benefits, all better than the documentation and anything else I’ve found.

  • @Deathhead68
    @Deathhead68 Před 2 lety +2

    Had missed the memo on this one. Thanks, this was really informative!

  • @ristopaasivirta9770
    @ristopaasivirta9770 Před rokem +11

    Thank you for this video.
    As Unity 2021 LTS now supports spans this gave a really good introduction and explanation on how to use them.
    Also the ref struct is valuable information since I have some very short lived structs for triangles and other mesh-related objects that only live for the duration of the method.

  • @kodikodi9948
    @kodikodi9948 Před 4 měsíci

    this is the first explanation of Span that made sense to me.
    thank you!!

  • @DepressionAlgorithm
    @DepressionAlgorithm Před 2 lety +28

    Didn't learn anything new in this, but I'm impressed by your presentation. I would have more quickly learned how Span works if this was the first video I saw about it.

  • @Sgro81
    @Sgro81 Před 2 lety

    Nothing new under the sun but very well explained. It's useful to have this kind of videos around, proper knowledge should be distributed like this.

  • @binjozoken6055
    @binjozoken6055 Před 2 lety +2

    To me, these are the best technical videos on the net, even though about 95 percent of them are over my head. This video, however, was worthy of getting a bowl of popcorn, sitting back and just watching. Thanks a bunch, Nick.

  • @Pouya..
    @Pouya.. Před rokem +1

    I'm a senior developer with 10+ years of experience and I learn so much from your videos thanks in advance

  • @pedrocunha4322
    @pedrocunha4322 Před rokem

    I really appreciate your content Nick, helped me a lot improve the way i code :)

  • @Sad-Lemon
    @Sad-Lemon Před 2 lety

    Very nice explanation. Will surely be helpful in my work. Thanks!

  • @coffee22able
    @coffee22able Před 2 lety

    Great Video, thanks for the board explanation, it was awesome!

  • @arlvinmoyo9290
    @arlvinmoyo9290 Před rokem

    Amazing delivery. Thank you!

  • @Cassiopeja22
    @Cassiopeja22 Před 2 lety

    Excellent explanation, Nick! Thank you very much. :)

  • @davemasters
    @davemasters Před 2 lety

    Brilliantly explained, as per usual.

  • @PontusWittenmark
    @PontusWittenmark Před 2 lety

    Great explanation, Nick 👍

  • @jonowilliams26
    @jonowilliams26 Před 2 lety

    Quality content as always !

  • @andreaskarz
    @andreaskarz Před 2 lety

    Wow, I never see before but I will us it in the next projects -- thank you.

  • @KeesSchollaart
    @KeesSchollaart Před 2 lety +8

    Curious to learn how it deals with byte arrays, compared to working with strings like you demo'd.

  • @milanmladenovic
    @milanmladenovic Před 2 lety

    Hi Nick, great video as usual :)

  • @tzurdo1
    @tzurdo1 Před 2 lety +1

    Another great video Nick!
    A small question - is there a way to split Span into array\list of Spans?
    Or actually, what is the best way to do it, without iterating by myself over the Span?

  • @my_temporary_name
    @my_temporary_name Před 2 lety

    Great presentation, thank you!

  • @rainezombi3431
    @rainezombi3431 Před rokem

    Your short brought me here. Good stuff!

  • @misomalu
    @misomalu Před 2 lety

    Excellent video and presentation.

  • @KeithSwanger
    @KeithSwanger Před 2 lety

    Nice explanation. Thank you!

  • @user-ss9qg6ke5t
    @user-ss9qg6ke5t Před 2 lety

    You are amazing! Thanks for your explanations

  • @im1in260m
    @im1in260m Před rokem

    Thank you Nick. Your videos are easy to understand, neat and to the point. I looked on your web site at the courses and wanted to know if the Dependency injection was based on a third party app. I was unable to locate a way to contact you there.

  • @hirenpatel2236
    @hirenpatel2236 Před 2 lety

    Nicely explained!

  • @oshastitko
    @oshastitko Před 26 dny

    Very cool explanation! Thank you!

  • @mehdihadeli
    @mehdihadeli Před 2 lety

    Hi, Thanks for your great video,
    Please record a view about diagnostics and tracing in .NET 5.

  • @stuartbooth8232
    @stuartbooth8232 Před 2 lety

    Great vid easy to follow thankyou

  • @tianjinghan1
    @tianjinghan1 Před rokem

    That is a great video, thanks, Nick. May I ask what IDE you are using?

  • @xinzhouping
    @xinzhouping Před 2 lety +4

    you should make a follow up video on ref structs if you haven't already.

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

    Good video, very insightful !

  • @gbelkin4
    @gbelkin4 Před 2 lety

    Brilliant as usally, Nick :-)

  • @AB-fb1ve
    @AB-fb1ve Před 2 lety

    Span is a powerful structure but has some limitation, what about Memory and what is the difference between them

  • @HomeSlize
    @HomeSlize Před 2 lety

    good stuff! thanks for sharing.

  • @amirdar
    @amirdar Před rokem

    Great video as always!
    in 2:26 how do you get to that debugger window with the memory tab ?

  • @scabendlin
    @scabendlin Před rokem

    wohoaaaa!!! now i understand a bit more the use span and garbage collectors....thanks nick!!

  • @rifatislamrakesh
    @rifatislamrakesh Před rokem

    Marvelous ! To the point. Respect !

  • @JtendraShahani
    @JtendraShahani Před rokem

    Hi. Thank you for the tutorials. I have learned a lot. I wanted to know how do you get the results inline. Thank you.

  • @Cruz0e
    @Cruz0e Před 2 lety

    if I understand this well, when you use the span, like:
    Readonly dateAsSpan = _dateAsText;
    you make a new variable called "dateAsSpan" but it's not allocating new memory for the "value" itself (in the heap), but instead just basically stores a reference, similarly when in c (normal C, not ++ or sharp) if I had a function like this
    void double_it(int *j) { j *=2 }
    using "int *j" instead of "int j" (* means that you pass by memory address reference instead of value)

  • @RichardNobel
    @RichardNobel Před 2 lety +7

    Should we refer to the _Span_ Slice method's start _index_ as... *"Spandex"* ? 😜
    When a (male) programmer is very good at using Span... is he "SpanKing" ? 👑
    (Or even Span heh). 🤴🏻

  • @TheCMajor9th
    @TheCMajor9th Před 2 lety

    great example m8 ty for the presentation

  • @bomite
    @bomite Před 2 lety

    Nice, thanks for that!!!

  • @tehsimo
    @tehsimo Před 2 lety

    That memory view in rider is awesome

  • @m0ment219
    @m0ment219 Před 2 lety

    This is... I can't believe how many times this could've helped me...

  • @tobiasj8019
    @tobiasj8019 Před 11 měsíci

    Very nice and helpfully 🎉

  • @MarioRamosMontesinos
    @MarioRamosMontesinos Před 2 lety

    Nice content!

  • @minciNashu
    @minciNashu Před 2 lety +2

    When you talk about allocation, it's important to stress that span doesn't really copy the source memory on the stack. The span object itself - containing probably a starting pointer and a max size - is created on the stack.

    • @Maxi-xw1jb
      @Maxi-xw1jb Před rokem

      Very true👆He should explaine it, otherwise it's misleading

  • @paultaylor2054
    @paultaylor2054 Před rokem

    thank you so much

  • @easycodeunity3d14
    @easycodeunity3d14 Před 2 lety

    Thank you very much

  • @yonatankarni8867
    @yonatankarni8867 Před 2 lety

    In comparison to C- span sound like a pair of pointers, and slice moves one of them.
    I hope I got the idea of this feature thanks!

  • @bovineox1111
    @bovineox1111 Před rokem

    Great video. I believe application only stops (completely) for GC when using workstation GC as opposed to server GC - you should compare the differences as they are quite striking and too long to go into here.

  • @eperez_yt
    @eperez_yt Před 2 lety

    Nice! I learned a new C# feature. Span look like pointers, so I'd have liked to know what would have happened if dateAsText had changed, and make sure if span really works like pointers. (:
    BTW i appreciate your video.

  • @TheAndiKurz
    @TheAndiKurz Před 8 měsíci

    The Span.ToString() method would allocate heap memory because strings are immutable, right?

  • @marksmod
    @marksmod Před rokem

    Isn't the ReadonlySpan allocating at least a copy of the string on the heap?
    For example, consider:
    string s = "123";
    ReadOnlySpan span = s;
    Console.WriteLine(int.Parse(span.Slice(0,2)));
    s = "321";
    Console.WriteLine(int.Parse(span.Slice(0,2)));
    produces:
    12
    12
    Oh, since strings are immutable in this language, the second time we assign to »s« we actually perform a second heap allocation, and »span« can happily use the address to which »s« pointed to when »span« was defined. And some smart-pointer-like stuff.

  • @user-py9cy1sy9u
    @user-py9cy1sy9u Před 2 lety

    Its nice to see that D is benefiting C#

  • @rossthemusicandguitarteacher

    This is great.

  • @harag9
    @harag9 Před 2 lety +2

    Great vid Nick, and there's me still working in c#7, .NET 4.8 & WinForms... I'm so far behind these days, but good to see new features in c#. I just wish the company I worked for didn't work on 15-20 year old projects...

    • @aminejadid2702
      @aminejadid2702 Před 2 lety +2

      don't worry, it's the same for me. Working with .Net framework 4.6.1 ! But i never stop learning new technologies. It is the only way

    • @harag9
      @harag9 Před 2 lety +1

      @@aminejadid2702 Same here, but I'm now losing interest doing it in my spare time, so unless I do it at work I lose the new skill.

    • @RealisableSoftware
      @RealisableSoftware Před 2 lety

      Add the System.Memory Nuget package. It's not everything that you get with core, but you get some benefit.

    • @aminejadid2702
      @aminejadid2702 Před 2 lety

      @@harag9 You can always find a better job.

    • @horowitzhill6480
      @horowitzhill6480 Před 2 lety +1

      .net 4.0 for me at work 🤣

  • @Radictor44
    @Radictor44 Před rokem +1

    Very good video - has helped to clear up my understanding of Span :)

  • @chiragdarji1571
    @chiragdarji1571 Před rokem

    Phenomenal!!!

  • @MultiMinors
    @MultiMinors Před 2 lety +4

    Span? I only know Div

  • @Dawhun
    @Dawhun Před 2 lety +1

    Hello, great video as usual :)
    Do the .ToString() really needed in the YearAsText() method return ? (end part of the video)

    • @nickchapsas
      @nickchapsas  Před 2 lety +1

      It did because at that point it is a ReadOnlySpan not a string and the Console.WriteLine method doesn't have an overload for it.

    • @TylerEich
      @TylerEich Před 2 lety +1

      @@nickchapsas I was wondering about YearAsText, line 21. Would the `ToString()` there still allocate on the heap and then implicitly converts the string to the ReadOnlySpan? I would’ve expected `return yearAsText` without the `ToString()`

    • @metaltyphoon
      @metaltyphoon Před 2 lety

      @@TylerEich No you don’t need to do ToString(). What you would be returning is a readonly ref struct to the caller and in there you can do the ToString()

    • @nickchapsas
      @nickchapsas  Před 2 lety

      @@TylerEich Sorry, Yeah not that you pointed out the line I understand what you mean. No that's a mistake. I added a pinned comment to explain that. I missed it because of ReadOnlySpan's implicit operator.

  • @SuperSpeed52
    @SuperSpeed52 Před 2 lety

    This is excellent for string manipulations

  • @SealedKiller
    @SealedKiller Před 2 lety +7

    So it's like a StringView, providing a view into the string pretty much.

    • @igorthelight
      @igorthelight Před 2 lety +2

      True
      For those who are not aware - It's std::string_view (after you #include ) in C++ 17

  • @easycodeunity3d14
    @easycodeunity3d14 Před 2 lety

    Awesome!

  • @marcomarek7734
    @marcomarek7734 Před rokem

    4:18 benchy was such a cute name 😍😂 didn't see that coming

  • @digitalpacman
    @digitalpacman Před 2 lety +3

    You should have maybe ran the test with a changing date every time. Strings in c# are instantiated once per instance and re-used. So "foo" in variable a and "foo" in variable b are both the same "foo" in memory. This likely will show a more realistic real world use case.

  • @Ayomikun
    @Ayomikun Před 2 lety

    Great video as always. Is this only ever useful for strings? Thanks

    • @nickchapsas
      @nickchapsas  Před 2 lety +1

      A span resembles an array so it can work as a byte array, int array and so on

  • @grainfrizz
    @grainfrizz Před 2 lety

    Very nice

  • @Guciubla
    @Guciubla Před 2 lety

    Great content!
    how does span compare to string builder in such scenarios?

    • @nickchapsas
      @nickchapsas  Před 2 lety +3

      string builder is used to create a string without having to deal with the immutability concerns. Span, even tho it could technically be used for something similar, primarily does the opposite.

  • @10199able
    @10199able Před 2 lety +2

    So this is how you use memory tab in Rider!

  • @CodingGustavo
    @CodingGustavo Před 2 lety +2

    Does int.Parse accept a Span? or theres a implicit conversion from Span back to string?

    • @nickchapsas
      @nickchapsas  Před 2 lety +2

      There is an overload with Span yeah

  • @bhavinmistry6262
    @bhavinmistry6262 Před 2 lety

    The best👌👌

  • @ivandrofly
    @ivandrofly Před 2 lety

    good stuff ;)

  • @EdKolis
    @EdKolis Před 3 měsíci

    In your last example you changed the return type but forgot to remove the ToString call from the method, negating the performance benefit. But thanks for explaining Span (and ref struct) in an understandable way; neither of those ever made sense to me until now!

  • @relaxfunplaynice
    @relaxfunplaynice Před 2 lety

    Is Span.Slice.ToArray() slightly faster than Buffer.BlockCopy or byte array copy using unsafe methods? (seems to be yes)

  • @mehmetedex
    @mehmetedex Před 2 lety

    this is brillant

  • @neriacohen5490
    @neriacohen5490 Před rokem

    Amazing

  • @JVimes
    @JVimes Před 9 měsíci

    Huh, wonder if they considered reimplementing/extending ArraySlice instead of making a new type.

  • @ivailomanolov6908
    @ivailomanolov6908 Před 2 lety

    Good video

  • @mabakay
    @mabakay Před 2 lety +1

    If int.Parse did not need to input string but span why Console.WriteLine need it?

  • @VasoPerasLikodric
    @VasoPerasLikodric Před 2 lety +1

    I guess that Parse method have span override. But what is happening if we need to use method which will except string.
    I guess it will have implicit conversion there.

    • @nickchapsas
      @nickchapsas  Před 2 lety

      If the method needs a string then the return string will be allocated but you can prevent any potential allocation during the mid-way processing in the method, depending on the workload. Also yeah, int.Parse has a span overload, including many other things that used to accept string.

  • @Aaron31056
    @Aaron31056 Před rokem

    At 10:40, wouldnt it be an offset of 2 instead of 3? Im guessing that its a 0 based offset, so the first value in the string would be index 0 and the third would be 2, so if we want to start reading the month which starts at index 2 the offset would then have to be 2 right? (+2 offset and 2 length).

  • @shoooozzzz
    @shoooozzzz Před 10 měsíci

    I **think** there is a little bug at the end of the video.
    Line 21 you are calling and returning `ToString()`
    As I just learned in your video, this would allocate memory on the heap requiring GC at some point.
    Again, this is all stuff I learned from YOU. So thank you

    • @shoooozzzz
      @shoooozzzz Před 10 měsíci

      Aaaaaaaaaaaaaaaaaaaaaaand I just saw the pinned comment 🤦🏻‍♂
      Oh well. Guess this shows I'm paying attention and learning stuff

  • @OvRaf
    @OvRaf Před 9 měsíci

    perfect

  • @dawidzyrek6481
    @dawidzyrek6481 Před 2 lety +26

    **Everyone** Nice video!
    **Me** Wait... A method can return multiple values?!

    • @KoScosss
      @KoScosss Před 2 lety +7

      Tuples!

    • @petrusion2827
      @petrusion2827 Před 2 lety +6

      Even before tuples you could use *out* or *ref* parameters to return multiple valuess without the need of making a new type every time. I miss both of those greatly when I have to work in java (among lots of other things).

    • @user-pu4qu9my5j
      @user-pu4qu9my5j Před 2 lety

      Sure. You also can return Monad like F# Descriminated Unions. In nutshell this is the simple value containers, but technically it incapsulated multiple values indeed. Tuples is the famous example of monads.

    • @rajm1976
      @rajm1976 Před 2 lety +1

      Yeah but don't. Unless they are related. Like co-ordinates or dates (you would use DateTime instead imo)

    • @rajm1976
      @rajm1976 Před 2 lety +1

      @@Qrzychu92 If want to return two unrelated things, they belong in seperate methods entirely. If it was co-ordinates or something like that, then Tuple would be fine.

  • @rajm1976
    @rajm1976 Před 2 lety +1

    In order to make use of the Span 'value' you still need to convert it ToString(), which as you say loses the value in Span, unless the resulting string is a concatination of a bunch of Span.Slice functions. So you could take the fact that Span is basically an Array and then join them together to produce the final result.

    • @nickchapsas
      @nickchapsas  Před 2 lety

      As you can see in the pinned comment the ToString() in the method that returns a ReadOnlySpan was a mistake. You don't need it and if you don't use it you don't allocate until the final ToString()

  • @igorthelight
    @igorthelight Před 2 lety +1

    6:15 - You could access String as an array too!
    But if you would try to change even just one char like that:
    string myString = "Hello!";
    myString [0] = 'h'; // This will not be compiled!
    It still would allocate a whole new string. StringBuilder do not behave like that tho so you could do that:
    var sb = new StringBuilder("Hello!");
    sb[0] = 'h';

    • @Dennis19901
      @Dennis19901 Před 2 lety

      The indexer of a string in C# is get only.
      What you wrote is invalid code.

    • @igorthelight
      @igorthelight Před 2 lety

      @@Dennis19901 Thanks! I pointed out that this line can't be compiled.

  • @DynotoeTube
    @DynotoeTube Před 2 lety +1

    So I wonder if there is a similar use of SPAN for a more common task of parsing CSV comma delimited strings?