Span – An abstraction over all types of memory available to .NET programs
github.com
github.com
I wrote a FileSpanStream class to implement BitTorrent file writes in BTSharp years ago.
While it's not targeted toward in-memory implementations, it is a similar type of wrapper abstraction and might be well understood by developers familiar with the "Span" abstraction (esp. after the Span<T> generic is in the BCL).
I can imagine scenarios where the FileSpanStream could be leveraged for non-BitTorrent use cases. (max-filesize constraints, load disribution, other, use your imagination).
I'm on mobile right now but I'll follow-up with a license-compatible contribution for consideration for inclusion.
P.S. Keep up the good work .NET Core Team. I've been keeping an eye on the project since you've been providing cross-platform distributions and it's extremely exciting. I loved working at Microsoft (especially when the .NET team with Brad Abrams was publishing things like .NET library design guidelines). I miss the .NET that I loved working with in 2004 and the .NET Core project is bringing me back one design at a time. Cheers.
Since strings are immutable and non-sharing, all substring calls will create copies of the substring. With Span<T>, you could instead simply request a span of the string and, with unification in the underlying typing, you can perform all of your string manipulation with no allocations or copying.
Both approaches have benefits and drawbacks, but apparently copying the sub-string seems to be best for the vast majority of cases and you only benefit from the shared buffer in select cases (also it's a great memory leak opportunity if you don't know how it's implemented). So I guess it makes sense for .NET to add the capability (in a more general form that also works for other things) instead of only having one or the other.
Span<T> conveniently side steps this issue by only existing on the stack, meaning that you can't stash away the span somewhere and accidentally keep the underlying buffer alive longer than necessary.
The fast representation makes the type automatically stack-only, i.e. the constraint
will be enforced by CLR type loader. This restriction should also be enforced by
managed language compilers and/or analyzers for better developer experience. For
the slow span, language compiler checks and/or analyzers is the only option (as
the runtimes won't enforce the stack-only restriction).You can already see this in the "ref parameters" feature in C# today: they can be parameters to methods but cannot be stored in fields. This implies that they can only exist on the stack.
Similarly, when we add support for ref-locals and ref-returns in C# 7 that will still disallow ref fields, so ref variables will still only be allowed on the stack.
Problem with that is that a small substring of a larger string prevents the data buffer of the larger string to be garbage collected.
That happened a lot when parsing files. Let's say you read a 1 GB, 10M row cvs file with a small string ID and 10 integers on each line. The strings should take maybe 100MB, but they will take 1GB. Oops.
The behaviour of the substring function changed to copy string data in JDK7 (after quite a bit of deliberation. There was a nice writeup of the results somewhere, but I can't find it)
Just last month I developed an algorithm to solve performance issues related to traversing a large graph. The algorithm required an array of hundreds of millions of structs and performance was very important (as one might assume when using a lot of RAM!). Allocating on the native heap worked like a charm!
My solution was too-coupled to the specific problem I was working on, I'll be looking to use Span<T> instead as soon as I have time to convert.
The use case for Span is more within the managed realm: it allows pointer-like manipulation of memory, without having to special-case it for each type.
And although anything with pointers is of course asking for trouble to some extent, you don't lose any safety in most scenarios (those not involving obvious giveaways like 'unsafe'...)
"Safe Systems Programming in C# and .NET"
https://www.infoq.com/presentations/csharp-systems-programmi...
Span<T> is a new type we are adding to the (.NET) platform to represent
contiguous regions of arbitrary memory, with perfromance characteristics on
pair with T[]. Its APIs are similar to the array, but unlike arrays, it can
point to either managed or native memory, or to memory allocated on the stack.