Question Why Memory and ReadOnlyMemory are struct?

skl2021

New member
Joined
Jun 8, 2021
Messages
2
Programming Experience
10+
Why the types Memory and ReadOnlyMemory are struct instead of class? As they generally are used on asynchronous calls and are moved to the heap.
 
Structs have lower overhead than classes and perform better. Since the goal of the Memory, ReadOnlyMemory, Span, and ReadOnlySpan structs is to help improve code performance, it would be kind of counter productive to use a high overhead mechanism.
 
Structs have lower overhead than classes and perform better. Since the goal of the Memory, ReadOnlyMemory, Span, and ReadOnlySpan structs is to help improve code performance, it would be kind of counter productive to use a high overhead mechanism.
Which overhead? Besides of allocating on the heap (and freeing thru GC).
 
Yes, it's the allocation and deallocation overhead. It's faster to allocate on the stack than to allocate on the heap (even with .NET's approach to memory allocation on the heap).
 
When Stroustrup was writing C++ 11, he initially wanted people to write code in a different way, and not just in C++; a way were people would not rely on GC, simply because they aren't very efficient. Some of the changes he was proposing to Microsoft at that time would have broken all previously developed applications had they followed his .net considerations, and hence why under his own recommendations, Microsoft opted to go the other way. But because of the direction Microsoft took with their frameworks development some ten to twelve years ago, Microsoft had an opportunity to change how we write code today, and for the better of all languages supported under .net. But they never went for it...because the consequences on pre-existent applications would have been to great and broken them. Using GC has become a standard reliance among developers today. I find it regrettable personally.

Structs are also underused today, and I nearly never hear nor see people using them, at least not properly. You should read Stroustrup: FAQ regarding why C++ doesn't have garbage collection. To quote :
Also, C++ supports programming techniques that allows memory management to be safe and implicit without a garbage collector. I consider garbage collection a last choice and an imperfect way of handling for resource management. That does not mean that it is never useful, just hat there are better approaches in many situations.
.net is mainly wrote in C#, but how its wrote is in-part dictated by the CLR/CLI which is wrote in C++ which is then broken into machine language (IL). The complexity should be evident how and why Microsoft introduced a GC for C#. When you call GC, it's called up in the CLR afaib. (Someone correct me on that). Anyway I believe this to be correct, and that is why they were introduced for calling-on in C#.

I have noticed OOP has improved a great deal as C# has matured. But with the reliance on automated memory management in C#, this has sadly led to a badly bloated framework. Not only that, but the use of GC is not very efficient all-round, because you are essentially still allocating memory when a GC is called to free up memory. Right? This was one of the reasons why Stroustrup was never a fan of GC as you have read above. That quote is from his own website. You can do some light reading on Managed Heaps, but if you are interested in memory management in application development, I recommend getting a good book/indebt articles on the subject. As any good literature would also cover the subject of class vs structs. Managed Heap Link for light reading : Fundamentals of garbage collection. You can find lot of resources on these subjects on Coding Horrors.
 
There is also the usage part of things.

If you have something like (I've elided some of the other initializations that the compiler would likely whine about):
C#:
class FooClass
{
    public int A;
}

struct FooStruct
{
    public int A;
}

class Bar
{
    public FooClass _fooClass = new FooClass();
    public FooStruct _fooStruct = new FooStruct();
}

:

var bar = new Foo();
bar._fooClass.A = 12;
bar._fooStruct.A = 12;

The access to bar._fooClass.A would have to first dereference bar, compute the offset of _fooClass reference within Bar, then dereference bar._fooClass, then compute the offset of A value within FooClass to be able to access bar._fooClass.A. You incur two memory hops (one to get to Bar and another to get to FooClass which ruins any memory caching/pipelining.

Compare that to bar._fooStruct.A would have to first dereference bar, compute the offset of _fooStruct value within Bar, then compute the offset of A value within FooStruct to be able to access bar._fooStruct.A. There is only one memory hop to Bar. A good optimizing compiler could coalesce the two offset computations into a single offset computation.
 
Some of the changes he was proposing to Microsoft at that time would have broken all previously developed applications had they followed his .net considerations, and hence why under his own recommendations, Microsoft opted to go the other way.
The pressure for Microsoft at that time was that all development mindshare was going to Java, and Microsoft recently losing it lawsuit with Sun regarding Java. So MS had to come up with something Java like that ran on something like a JVM. Also at that time, the industry believed heavily that the major cause of bugs was (1) memory leaks; and (2) unsafe use of pointers. Anders Hejlsberg (yes, another Danish computer scientist :)), came up with C#. I forget now who the key architects were for the BCL that runs under .NET Framework.
 
I've yet to join a forum on the net where someone posts a proper example of a proper use-case scenario of when to use struct vs classes. Lasse V. Karlsen answered this well on Stack Overflow : What's the difference between struct and class in .NET?
The pressure for Microsoft at that time was that all development mindshare was going to Java, and Microsoft recently losing it lawsuit with Sun regarding Java.
I forgot all about that. :) (Probably because it was 20 years back). Microsoft had the opportunity twelve years ago to make that redirection.

It wasn't only that though, there were a variety of reasons why they didn't take the alternate route, and given the facts; had they changed their direction at that time, they'd likely have faced lawsuits from those who's apps they'd broken.
 
Last edited:
Back
Top Bottom