Trying to reduce GC collections - c#

Can someone please tell me whether AddB below will result in less CLR allocations than AddA? I've examined disassembly and it looks to be the case but I'd like confirmation from the Experts please. Can someone Exchange this information with me please?
Cheers,
Charlie.
namespace A
{
struct Vec2
{
public float x;
public float y;
public Vec2 AddA(Vec2 other)
{
Vec2 v = new Vec2(); // Reference variable
v.x = x + other.x;
v.y = y + other.y;
return v;
}
public Vec2 AddB(Vec2 other)
{
Vec2 v; // Value variable
v.x = x + other.x;
v.y = y + other.y;
return v;
}
}
}

If Vec2 is a struct in both examples, by using Vec2 v = new Vec2(); you are not creating a reference to your struct, you are simply creating a new struct on your stack. If you don't use the new keyword, your struct is nevertheless created on the stack and you can initialize each field separately.
In that case, using the new keyword for a struct does't make much sense if your constructor doesn't accept some meaningful parameters to initialize the data in a single line.
If the first method uses a class instead of a struct, then it does create an object for GC to collect, unlike the second method. Since v in AddB is allocated on the stack, it is not collected, the stack is simply popped when your method is finished.

There's no guarantee for anything. Value items are not necessarily stored in the heap.
See The Stack Is An Implementation Detail by Eric Lippert, and the following second part.

The code in your AddA method simply does the same as:
public Vec2 AddA(Vec2 other) {
Vec2 v;
v.x = 0;
v.y = 0;
v.x = x + other.x;
v.y = y + other.y;
return v;
}
The parameterless constructor of a struct returns the default value for the struct, which is a value where all the members are zeroed out. The value is just returned by the call to the constructor, it's never allocated on the heap.
Also, a mutable struct is generally a bad idea. I would implement it like:
struct Vec2 {
public float X { get; private set; }
public float Y { get; private set; }
public Vec2(float x, float y) {
X = x;
Y = y;
}
public Vec2 Add(Vec2 other) {
return new Vec2(X + other.X, Y + other.Y);
}
}

Note that AddA and AddB do not differ in their memory behaviour, both will be allocated on the stack. What does make a difference is that AddB does not call the default constructor for the type and thereby leaves the fields of the Vec2 uninitialized, whereas AddA will zero them out first.
Having said that I'd imagine that the performance hit of zeroing the contents is probably not measurable (if the JIT compiler doesn't even remove it altogether anyway).

To add to the other answers:
Firstly, the code can be improved by using an appropriate constructor and thus omitting the tedious assignments. This isn't really optional: it should be done. Additionally, it would be good to implement such a structure as an immutable type, i.e. making the fields readonly so chances to it aren't at all possible: thus, you would implement pure value semantics.
Secondly, concerning the question of stack vs. heap allocation: I wouldn't bother too much here anyway: the kind of GC used in .NET is specialized to handle lots of such small allocations: your code would be the optimal scenario as far as the .NET GC is concerned. Don't try to avoid it.

Related

Constructor of a struct copying a struct

I have a struct which is for an Arc.
I created a constructor that accepts an Arc struct type and i want to basically copy the contents to the new struct i am creating but it seems to zero everything out - not sure if i am misunderstanding how this works.
This is what i have:
//constructor, take an arc - copy it but with a new radius
public Arc(Arc a, float radius)
{
this = a;
a.Radius = radius;
}
With the usage
Arc arc1 = new Arc(arc0, arc0.Radius + _width/2f);
arc1.Draw(Color.green,2);
Arc arc2 = new Arc(arc0, arc0.Radius - _width/2f);
arc2.Draw(Color.green,2);
For some reason arc1 and arc2 have default values for all its fields including the radius field.
I was expecting arc1 and arc2 to basically be copies of arc0 but with a new radius.
Is the use of this not applicable for non reference types or something? I can't see why else i am having this problem.
public Arc(Arc a, float radius)
{
this = a;
a.Radius = radius; // <-- This line is the problem
}
Your use of a.Radius = radius means you're overwriting the .Radius member of parameter a, not field this.a.
Value-types, including struct values in .NET, do not share identity - whereas reference-types (class instances, Object, etc) can do (and do by default). So, with limited exceptions, you can think of each struct-variable as holding its own distinct copy of the entire structure instance.
Change your code to this:
public Arc(Arc source, float radius)
{
this = source; // Copy `source` into `this`
this.Radius = radius; // Then overwrite `this.Radius`
}

C# cast float array to struct of floats

I have a float array in C# that stores data. However, I need to cast the data to structures like Vector2, Vector3 etc. The structures are holding only floats, so there is no data type conversion in the matter of bytes, only in access.
Eg.:
struct Vector3
{
public float x;
public float y;
public float z;
//plus some methods
}
I can copy the whole float array to the struct one manually by creating a new array, but that is kind of slow for big ones. I have tried to do conversion in unsafe code, but using generic is not working and creating special method for every struct I have is kind of "weird".
In C++ I have something like this:
float * arrayFloat = ....
Vector3 * arrayVector3 = reinterpret_cast<Vector3 *>(arrayFloat);
but that is not an option in C#...
Any ideas how to achieve this, or how to change the design?
you could add a constructor to your struct:
struct Vector3
{
public float x;
public float y;
public float z;
public Vector3(float[] vals)
{
if(vals.Length != 3)
throw new ArgumentException();
x = vals[0]; y = vals[1]; z = vals[2];
}
}
...elsewhere
float[] myFloats = { 0.0f, 1.1f, 2.2f };
var myVec = new Vector3(myFloats);
if you're asking if there is something that lets you do this without any work, the answer is no. Any conversion from an array to a struct of your choosing has to be implemented by you, preferably in your struct.
I believe this can work for your struct, using .NET Core 2.1's MemoryMarshal methods.
My answer here describes how. The essence is:
var vectors = MemoryMarshal.Cast<float, Vector3>(floatArray.AsSpan());
var firstVector = vectors[0];
This is C#'s equivalent of a reinterpret cast.
I'm new to C#, and i was struggling with the same problem, what i found useful is to use an enumerator which lazily converts every element on access:
IEnumerator<Vector3> Positions()
{
for (int i = 0; i < _positions.Length / 3; ++i)
{
yield return new Vector3(_positions[3*i],
_positions[3*i+1],
_positions[3*i+2]);
}
}
With this you don't need to copy the whole array and compiler most likely will not create new object of type Vector3 in memory instead it will use registers.

Is A Class Member Variable Bound Or Free (In Terms Of Combinators)?

While I realize I'm not being very rigorous, I'm pretty sure the definition of a combinator in simple terms is simply a function with no free variables. For example,
f(x,y) = x + y
would be a combinator and
f(x,y) = x * 2
would not be because y would be free.
So given that understanding would a member variable in a class definition be considered "free"? I'm guessing it would but I wanted to check my assumption. Code like this C# example:
namespace ConsoleApplication1
{
class BoundOrFree
{
private int _i = 0;
public int f(int x, int y)
{
return x + y + _i;
}
}
}
In the BoundOrFree.f member function is _i free? Would f therefore not be a combinator? I'm assuming the answer to both of those questions would be yes but I wanted to confirm my assumption.
would not be because y would be free
you misinterpret the "free" term in this case. Free variable is the one that was captured from the outer scope (via a closure). So f(x,y) = x * 2 is a combinator.
Answering your question
In the BoundOrFree.f member function is _i free? Would f therefore not be a combinator?
the BoundOrFree::f function is not a combinator, since it uses variables other than its only arguments.

Practical differences between classes and structs in .net (not conceptual)?

Whenever I tried to search about differences between classes and structs in C# or .net, I ended up with the conceptual overview of the two things like value type or the reference type, where the variables are allocated etc. But I need some practical differences. I have found some like different behavior of assignment operator, having constructors etc. Can anybody provide some more practical differences which will be directly useful while coding? Like the things works with one but not with other or same operation showing different behavior. And some common mistakes regarding these two.
Also please suggest where to consider using a struct instead of a class. And where the structs should not be used.
Edit:
Do I have to call the constructor explicitly or just declaring a struct type variable will suffice?(Should I make it a new question?)
OK, here are a few specific, practical differences:
A variable can be null if it’s a class, but is never null if it’s a struct.
default(T) is null for a class, but for a struct actually constructs a value (consisting of lots of binary zeros).
A struct can be made nullable by using Nullable<T> or T?. A class cannot be used for the T in Nullable<T> or T?.
A struct always has a public default constructor (a constructor with zero parameters). The programmer cannot override this constructor with a custom implementation — it is basically “set in stone”. A class allows the programmer to have no default constructor (or a private one).
The fields in a class can have default values declared on them. In a struct they can’t.
A class can inherit from another class, but a struct cannot be declared to derive from anything (it implicitly derives from System.ValueType).
It makes sense to use a class in object.ReferenceEquals(), but using a struct variable will always yield false.
It makes sense to use a class in a lock() statement, but using a struct variable will cause very subtle failure. The code will not be locked.
On a 32-bit system, you can theoretically allocate an array of up to 536,870,912 references to a class, but for a struct you need to take the size of the struct into account because you are allocating actual instances.
Structs in a container can only be modified if the container is a built-in array:
struct Point { public int x, y; void Move(int dx, int dy) { x += dx; y += dy; } }
...
Point[] points = getPointsArray();
points[0].Move(10, 0) = 10;
// points[0].x is now 10 higher.
List<Point> points = getPointsList();
points[0].Move(10, 0);
// No error, but points[0].x hasn't changed.
For this reason, I strongly favour immutable structs:
Point Move(int dx, int dy) { return new Point(x + dx, y + dy); }
...
points[0] = points[0].Move(10, 0); // Always works.
General observation: classes are usually better. Structs excel when you want to hold small, conceptually atomic data structures such as Point, Complex (number), Rational, etc.
structs, as they are value types, are copied on assignment; if you create your own struct, you should make it immutable, see Why are mutable structs evil?
Sometimes you don't want what you're passing to be mutable, and since a mutable struct may just be pure evil, I'd steer clear of ever creating one :) Here's an example a situation:
class Version:
class AccountInfo {
public string OwnerName { get; set; }
public string AccountNumber { get; set; }
}
struct Version:
struct AccountInfo {
public string OwnerName;
public string AccountNumber;
}
Now picture you called a method like this:
public bool TransferMoney(AccountInfo from, AccountInfo to, decimal amount)
{
if(!IsAuthorized(from)) return false;
//Transfer money
}
A struct is a Value type, meaning a copy gets passed into the method. The class version means a reference gets passed into the method, you wouldn't want for example the account number to be changeable after the authorization passed, you want nothing to be changed in an operation like this...you want an immutable value type. There's another question here asking why mutable structs are evil...any operation where you wouldn't want anything affected by the reference object changing, would be a practical place where a struct may fit better.
The example above may be somewhat silly, but the point is any sensitive operation where the passed in data shouldn't change in another thread or by any means really would be a place you look at passing by value.
Where they are allocated (heap vs. stack) is not something you really care about while you use them (not that you should disregard this - you should by all means study the differences and understand them).
But the most important practical difference you will come across the first time you decide to replace your class with a struct, is that structs are passed by value, while class instances are passed by reference.
This means that when you pass a struct to a method, a copy of its properties is created (a shallow copy) and your method actually gets a different copy than the one you had outside the method. When you pass an instance of a class, only a reference to the same place in memory is passed to the method, and your method is then dealing with exactly the same data.
For example, if you have a struct named MyStruct, and a class named MyClass, and you pass them to this method:
void DoSomething(MyStruct str, MyClass cls)
{
// this will change the copy of str, but changes
// will not be made to the outside struct
str.Something = str.Something + 1;
// this will change the actual class outside
// the method, because cls points to the
// same instance in memory
cls.Something = cls.Something + 1;
}
when the method ends, your class' property will be incremented, but your struct's property will remain unchanged, because str variable inside the DoSomething method does not point to the same place in memory.
The singularly important practical difference is that structs are value types, whereas classes are reference types. That has a few implications.
First of all, structs are copied on assignment. These two code blocks will have a different result (please note, normally you should neither use public fields nor mutable structs, I'm doing this for demonstration purposes only):
struct X
{
public int ID;
public string Name;
}
X x1 = new X { ID = 1, Name = "Foo" };
X x2 = x1;
x2.Name = "Bar";
Console.WriteLine(x1.Name); // Will print "Foo"
class Y
{
public int ID;
public string Name;
}
Y y1 = new Y { ID = 2, Name = "Bar" };
Y y2 = y1;
y2.Name = "Baz";
Console.WriteLine(y1.Name); // Will print "Baz"
X and Y are exactly the same, except that X is a struct. The results of this are different because every time we assign an X, a copy is made, and if we change the copy then we aren't changing the original. On the other hand, when we assign the contents of y1 to y2, all we've done is copied a reference; both y1 and y2 refer to physically the same object in memory.
The second consequence of structs being value types is generic constraints. If you want to pass in value types, the name of the constraint is literally "struct" or "class":
public class MyGeneric<T>
where T : struct
{ ... }
The above will let you create a MyGeneric<int> or MyGeneric<X>, but not a MyGeneric<Y>. On the other hand, if we change it to where T : struct, we're no longer allowed to create either of the first two, but MyGeneric<Y> is okay.
Last but not least, you need to use structs when writing interop, because with structs you're able to guarantee a specific arrangement in memory.
The link Tejs provided (http://www.jaggersoft.com/pubs/StructsVsClasses.htm) is a good explanation (although it is a bit out of date, particularly on the explanation of events).
The most import practical difference is that a struct is a value type, meaning it is passed by value rather than by reference. What this really means is that when a struct is passed as an argument, it is actually passed by copy. As a result, operations on one instance of a struct do not affect other instances.
Consider the following code:
struct NumberStruct
{
public int Value;
}
class NumberClass
{
public int Value = 0;
}
class Test
{
static void Main()
{
NumberStruct ns1 = new NumberStruct();
NumberStruct ns2 = ns1;
ns2.Value = 42;
NumberClass nc1 = new NumberClass();
NumberClass nc2 = nc1;
nc2.Value = 42;
Console.WriteLine("Struct: {0}, {1}", ns1.Value, ns2.Value);
Console.WriteLine("Class: {0}, {1}", nc1.Value, nc2.Value);
}
}
Because both ns1 and ns2 are of the NumberStruct value type, they each have their own storage location, so the assignment of ns2.Number does not affect the value of ns1.Number. However, because nc1 and nc2 are both reference types, the assignment of nc2.Number does affect the value of nc1.Number because they both contain the same reference.
[Disclaimer: The above code and text taken from Sams Teach Yourself Visual C# 2010 in 24 Hours]
Also, as others have already pointed out, structs should always be immutable. (Yes, in this example the struct is mutable but it was to illustrate the point.) Part of that means that structs should not contain public fields.
Since structs are value types, you cannot inherit from a struct. You also cannot derive a struct from a base class. (A struct can implement interfaces, however.)
A struct is also not allowed to have an explicitly declared public default (parameterless) contstructor. Any additional constructors you declare must completely initialize all of the struct fields. Structs also cannot have an explicitly declared destructor.
Since structs are value types, they shouldn't implement IDisposable and shouldn't contain unmanaged code.
Here's an interesting link: http://www.jaggersoft.com/pubs/StructsVsClasses.htm
For the most part though, there isn't much of a compelling reason to use structs when classes offer far more to the developer.

How to handle value types when embedding IronPython in C#?

There is a well known issue when it comes to using .NET value types in IronPython. This has recently caused me a headache when trying to use Python as an embedded scripting language in C#. The problem can be summed up as follows:
Given a C# struct such as:
struct Vector {
public float x;
public float y;
}
And a C# class such as:
class Object {
public Vector position;
}
The following will happen in IronPython:
obj = Object()
print obj.position.x # prints ‘0’
obj.position.x = 1
print obj.position.x # still prints ‘0’
As the article states, this means that value types are mostly immutable. However, this is a problem as I was planning on using a vector library that is implemented as seen above. Are there any workarounds for working with existing libraries that rely on value types? Modifying the library would be the very last resort, but I'd rather avoid that.
There's no need to modify the library, just use a proxy.
struct Vector {
public float X;
public float Y;
}
class BetterVector {
public float X;
public float Y;
public Vector Optimized { get { return new Vector(X, Y); } }
}
class Object {
public BetterVector Position { get; set; }
}
Now the Python code can set fields as normal and your code can call Optimized when it needs to feed the data to OpenGL or XNA or whatever you're using.
You can even use implicit coercion if calling Optimized seems like too much work:
class BetterVector {
// ...
public static implicit operator Vector(BetterVector v) {
return v.Optimized;
}
}
When you call
obj.position.x = 1
What you get is that the obj object gets you an instance of the position struct, which it essentially makes a copy of, so, setting the X value doesn't get propogated.
What you're saying is that obj.position = Vector(1,0) is what you should be doing. Similar things happen in C#.
Edit - possible work around.
If you don't want to set up the constructor, I believe this will work:
obj = Object()
pos = obj.position; # gets the object
pos.x = 1
pos.y = 2
obj.position = pos # I'm not sure if this line is necessary
The only way I've found to update structs is to make use of the fact that you can specify any public field/property when creating a struct. The syntax looks like named/optional parameters in Python.
namespace StructExample
{
public struct MyStruct
{
public int x;
public int y { get; set; }
}
public class MyClass
{
public MyStruct a;
}
}
We can use the classes in IronPython like this:
>>> foo = MyClass()
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a.x = 1 # doesn't work!
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a = MyStruct(x=1,y=2)
>>> print "%d:%d" % (foo.a.x, foo.a.y)
1:2
It would be nice if Python had a syntax like the F# 'with' for creating a new struct, copying the fields from the old one. Unfortunately we have to specify all the fields when cloning a struct.
Rather puzzling that you ended up in such a corner. In python (tried this on IronPython 2.6.1, .Net 4.0) the equivalent code would be about this:
>>> class a:
... x = 0
... y = 0
...
>>> class b:
... Vector = a()
...
>>> c = b()
>>> c.Vector.x = 1
>>> print c.Vector.x
1
Note there is one difference between my pseudo code and yours - static property is assigned an instance of a class, not just left with type definition. As a side effect, an actual instance of a class is initialized as b.Vector when b is instantiated.
(The pseudo-code is still "broken" - the initialization must go into def init(self), but that's a different story)
The moral of the example, instead of leaving "public Vector position" uninitialized, build initialization of "position" into class Object.

Categories

Resources