C# 7.2: Understanding Span

Sign in to queue

Description

Span is a new language feature that significantly improves performance. Learn about Span and how you can benefit from improvements we've made up and down the stack. Learn how to use Span in your own code.


Product info: www.dot.net
Learn more: docs.microsoft.com/en-us/dotnet/csharp/
Documentation: aka.ms/csharp72

For more information, check out this course on Microsoft Virtual Academy:

Tags:

.NET, C#

Day:

0

Session Type:

On-demand

Code:

T125

Embed

Download

The Discussion

  • User profile image
    YourMotherIn​Law

    new ReadOnlySpam<Comment>();

  • User profile image
    MikeEEE

    Cooooooool... super solid overview. Nice work, Mr. Parsons!

  • User profile image
    Alois Kraus

    Very good overview. I hope I will see these things also light up in the full .NET Framework.
    Is it possible to target .NET 4.6 and reference some Nuget packages to create Span/Memory based APIs today which will run faster once .NET 4.7.2 arrives?

  • User profile image
    terrajobst

    @YourMotherInLaw: I see what you did there. But you need to reduce the number of comments you're allocating ;)

    @Alois Kraus:

    I hope I will see these things also light up in the full .NET Framework.


    Span<T> will be available for .NET Framework via a NuGet package. This won't give you all the features that would require adding APIs to existing types.

    Is it possible to target .NET 4.6 and reference some Nuget packages to create Span/Memory based APIs today which will run faster once .NET 4.7.2 arrives?


    Yes, but Span<T> is only available as a preview. I won't ship as a stable before next year.

  • User profile image
    A D

    I think the ClosedCaption engine could do with some more hints on this video...

  • User profile image
    Maf2

    I tried your demo in VS2017 15.5 Preview 4. I can't find the AsReadOnlySpan() extension method. I have referenced the System.Memory NuGet package version 4.4.0-preview2-25405-01. Do I need a newer one?

    Fons

     

     

  • User profile image
    Issac

    Sorry, didn't understand much of the explaining.
    Maybe if it was with graphics an intermediate programmer would understand.

  • User profile image
    markadamson

    In the Memory<T> example, what would have happened if you didn't do the slicing but just said memory.Span?

  • User profile image
    David

    On reason for Span<T> being a stack-only type is the struct tearing issue explained here:

    https://github.com/dotnet/corefxlab/blob/master/docs/specs/span.md#struct-tearing

    How do you overcome struct tearing issues with the Memory<T> type?

  • User profile image
    Gaston Simone

    Apart from the new useful features explained in this video, it is also quite pleasant to realize a software engineer working in the C# compiler is a Vim user and also user and the creator of the amazing VsVim plugin for Visual Studio! Jared, I admire you and thank you for that amazing plugin.

  • User profile image
    antklc

    Unless I'm missing something, why not just build these functions intrinsically into string, et al? I mean isn't the job of "managed" languages to handle memory allocation, etc, and take it away from the hands of the programmer?

  • User profile image
    machish

    I'd like to see the URLs for the links at 15:30 (API Guidelines, Vision Doc). It's just tantalizing us! :)

  • User profile image
    msedi

    Very nice work. However it would be much nicer if a more generic approach would be preferred where Span<T> is part of it. I mean something like an IArray<T> that Span<T> could implement. Also the ArraySegment<T> lacks features like the this[] notation (I have to cast to IList<T> to get access to this[].

    Having something like IArray<T> and some Array<T> could allow developers having their own solution and don't have to rewrite code on and on again when new features like Span<T> comes up.

    Arrays are currently either too strict if the array is used as a typed array, but is completely compile time unsafe if the Array type is used.

    If, for example I have a method to add two arrays, I need a function like this

    static float[] Add(float[] a, float[] b);

    now I have to rewrite the code to make it work with Span<T>

    static Span<float> Add(Span<float> a, Span<float> b);

    If I have a list

    static IList<float> Add(IReadOnlyList<float> a, IReadOnlyList<float> b);

    If I want to couple array and list to make things work:

    static T Add(T a, T b) where T : IList<float>;

    In the implementation above even if I use an array as parameter the implementation needs to use the this[] indexer of the list, which is awfully slow. Since Span<T> does not implement IList<T> I still have to use a different approaches.

     

    Maybe this is something to discuss.

     

     

     

     

  • User profile image
    jaredpar

    @markadamson:

     

    > In the Memory<T> example, what would have happened if you didn't do the slicing but just said memory.Span?

     

    In that case it would return a Span<T> that represented the entire memory segment contained in the Memory<T> instance. 

     

     

    @David:

     

    > How do you overcome struct tearing issues with the Memory<T> type?

     

    As you noted since Memory<T> is a struct and storable on the heap it is subject to tearing problems. The difference though is the tearing cannot create type safety issues. The structure of Memory<T> allows for the validation that bounds are still legal.

    For example in the case of arrays it is possible to verify the index and length are legal identifiers. For Span<T> to have similar safety it would need to do this non-trivial validation on every index operation. That would severely impact performance.

    This does mean though that tearing can be used to increase the amount of elements you can view in a Memory<T> instance. For example if I had a Memory<T> restricted to see one element of an array, it would be possible to use tearing as a method to see other elements in the array. But I would never be able to create a Span<T> that accessed elements before or after the array.

    @msedi

    > Having something like IArray<T> and some Array<T> could allow developers having their own solution and don't have to rewrite code on and on again when new features like Span<T> comes up.

    Take a look at OwnedMemory<T>. That is our generic solution for providing contiguous memory that can be used with Memory<T> and Span<T>. 

    @Gaston Simone:

    > thank you for that amazing plugin.

    Always feels good to hear that people are enjoying VsVim. Thank you :) 

     

     

     

     

     

  • User profile image
    char

    char though, not car

  • User profile image
    dzmitry

    Is see `T*`. Did C# got generics over pointers or it is just figure of speech? Is there such mechanism on IL level?

    Overall good presentation, where to download slides and source code? 

    And span length is int, which is max 2GB of bytes.

  • User profile image
    sektor

    Cool subtitles: "...implicit conversion from a RACE to both span and read-only span..."

  • User profile image
    msedi

    @jaredpar: I understand your point, but I would prefer a more global solution. Currently Span<T> and Memory<T> and also OwnedMemory are it's own datatypes that do not implement an interface. If there would at least be some interface that would also be implemented by other "array-like" types like, List<T>, Collection<T>, Array, etc. It would make it more flexible.

     

    As ReadOnlyList<T> was introduced also already existing classes were extended by implemting IReadOnlyList<T>, etc.

     

    BTW: I have tried Span<T> over a regular array additions. On my machine it was a factor of 2 slower, compared to the array addition. I personally thought that might be faster (if not equal). 

    Maybe I didn't use the correct runtime. Which one should I use. Or do I have to wait until .NET 4.7.2?

     

Add Your 2 Cents