Thread overview
[OT] .net is getting slices
Jul 13, 2017
Kagamin
Jul 13, 2017
Stefan Koch
Jul 13, 2017
jmh530
Jul 13, 2017
Kagamin
Jul 14, 2017
Kagamin
Jul 14, 2017
Kagamin
July 13, 2017
http://adamsitnik.com/Span/
July 13, 2017
On Thursday, 13 July 2017 at 14:30:42 UTC, Kagamin wrote:
> http://adamsitnik.com/Span/

It's a stack-only type. Wow. It totally sucks!

July 13, 2017
On Thursday, 13 July 2017 at 14:34:56 UTC, Stefan Koch wrote:
>
> It's a stack-only type. Wow. It totally sucks!

Huh? Take a look at the "Using Span" section.
July 13, 2017
On Thursday, 13 July 2017 at 17:08:38 UTC, jmh530 wrote:
> Huh? Take a look at the "Using Span" section.

It's indeed stack-only for safety reasons. On heap can be stored a span promise, that can be resolved to a span on stack.
July 14, 2017
On Thursday, 13 July 2017 at 17:08:38 UTC, jmh530 wrote:
> On Thursday, 13 July 2017 at 14:34:56 UTC, Stefan Koch wrote:
>>
>> It's a stack-only type. Wow. It totally sucks!
>
> Huh? Take a look at the "Using Span" section.

`new T(args)` does not always heap allocation in C#, unlike D.
When `T` is a `struct`, `T t = new T(args)` in C# is equivalent to
`auto t = T(args)` in D - i.e. `t` is allocated on the stack.

I have to agree with Stefan here. Even as a C# user, Span<T> of marginal
usefulness compared to D's built-in slices. Yes, it's a much needed
improvement for library writers, but still most of .NET's API won't
support it for at least several years, so it's essentially useless for
application developers. Put on top of that the lack of `const` type
constructor, the PITA ref type requirements [1] (quite alien to most C#
developers), the inability to use atomic instructions to update it
concurrently, and most of all - being close to unusable in generic code.

These kinds of foundational types must be there from the start. Regardless
of the .NET Native hype, .NET will never be suitable for high-performance
applications. 95% of the frameworks were never written with performance in
mind (only ASP.NET Core and EF Core come to mind as written in a perf
sensitive manner). Performance was almost always an afterthought.
Consider the following - I have a relatively trivial WPF app that undergoes
5-10 GC collections per second during window resize, while being
completely idle otherwise. Even on a desktop Core i7 this looks extremely
sluggish. WTF???

[1]: https://github.com/dotnet/csharplang/blob/master/proposals/span-safety.md
July 14, 2017
On Friday, 14 July 2017 at 06:05:42 UTC, Petar Kirov [ZombineDev] wrote:
> the inability to use atomic instructions to update it
> concurrently

That's a problem for D too.

> Consider the following - I have a relatively trivial WPF app that undergoes
> 5-10 GC collections per second during window resize, while being
> completely idle otherwise. Even on a desktop Core i7 this looks extremely
> sluggish. WTF???

I don't think WPF was meant to be lightweight.
July 14, 2017
On Friday, 14 July 2017 at 10:44:36 UTC, Kagamin wrote:
> On Friday, 14 July 2017 at 06:05:42 UTC, Petar Kirov [ZombineDev] wrote:
>> the inability to use atomic instructions to update it
>> concurrently
>
> That's a problem for D too.

core.atomic supports 2 * (void*).sizeof atomicLoad, atomicStore and cas (compare-and-swap) on platforms that support it (x86 and x86_64 for sure, and for others you have to check what libatomic (GCC) and llvm do).
Rereading the article again I noticed that they use the horrid Pointer + Offset + Length representation only for old runtimes, but use Pointer + Length for new ones.
Regardless of that, the only value-types that you perform atomic operations in .NET are int, long, IntPtr, float and double - see https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked?view=netframework-4.7.
July 14, 2017
On Friday, 14 July 2017 at 10:44:36 UTC, Kagamin wrote:
>
> I don't think WPF was meant to be lightweight.

Unfortunately, this is also true for most .NET libraries / frameworks.


July 14, 2017
On Friday, 14 July 2017 at 12:25:47 UTC, Petar Kirov [ZombineDev] wrote:
> core.atomic supports 2 * (void*).sizeof atomicLoad, atomicStore and cas (compare-and-swap) on platforms that support it (x86 and x86_64 for sure, and for others you have to check what libatomic (GCC) and llvm do).

If it's not cross-platform, that's a problem.
July 15, 2017
On Friday, 14 July 2017 at 12:50:56 UTC, Kagamin wrote:
> On Friday, 14 July 2017 at 12:25:47 UTC, Petar Kirov [ZombineDev] wrote:
>> core.atomic supports 2 * (void*).sizeof atomicLoad, atomicStore and cas (compare-and-swap) on platforms that support it (x86 and x86_64 for sure, and for others you have to check what libatomic (GCC) and llvm do).
>
> If it's not cross-platform, that's a problem.

In theory yes, in practice probably not. Are you worried that your code needs to run on platforms where bytes are 9-bit wide? What's more, not all CPUs support atomic loads and stores of 8 bytes, so .NET's Interlocked API that takes System.Double arguments is not cross-platform either.
I personally prefer D's approach where you can check at compile-time for has64BitCAS on 32-bit targets and has128BitCAS on 64-bit ones and write your algorithms accordingly. Design-by-Introspection FTW.