C# Structs-Properties Overhead

hey guys, a quick search didn’t really yield anything useful, so i was wondering about this:

i am very diligent in using encapsulation and so my classes almost always look something like

class {
GameObject _go;
Vector3 _vec3;

public Vector3 Vec3 { get; set; }
public GameObject Go { get; set; }

now in case of the game object i simply query a pointer so np there, but what about the vector3/vector2/color and other struct properties? if i have code like

transform.position = something.Vector3Property;

other than the vector3 being copied onto transform.position, do i risk also triggering another unnecessary copy by calling the vector3 property, or can i rely on the compiler/script interpreter (or however unity translates this) to inline that call

then, what about something like this

class A:
B myB;
Vector3 myVec3;
void Update() {
   myB.SomeMethod(myVec3);
}

...
class B:
void SomeMethod(Vector3 vec3) {
  // read access to vec3
}

this surely must create an unnecessary copy of all 3 floats on every update call on every gameobject that has an A monobehaviour
should i instead pass the vector3 as a ref to improve performance (preemptively)?

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”

And in your case, it’s really a potential useless optimization. I’m not even sure if passing a Vector3 around is even benchmarkable properly under a tens or hundreds of thousands of occurrences.

I doubt it. Even passing a ref you’re still copying memory, just instead of copying a whole vector3 structure you’re copying an address.

k thanks

maybe this article gives you some insight. albeit i agree with the others that such optimizations often lead to “ugly” code which reduces readability. consider that code is way more often read than written so the effort should be put to make reading easy. IF you encounter a bottlenek by profiling THEN you try to optimize the code.
and in case of uncertainty just profile both methods yourself and see if its worth it. optimizations sometimes yield unexpected results.

I believe that passing by ref also makes that a mutable struct.

I don’t get what you mean; why/when wouldn’t a struct be mutable?

Structs are immutable by definition.

struct SomeStruct
{
    public int SomeValue;

    public void SetSomeValue(int newValue)
    {
        this.SomeValue = newValue;
    }
}

public void SomeMethod()
{
    List<SomeStruct> structs = new List<SomeStruct>();
    SomeStruct item = new SomeStruct();
    item.SomeValue = 10;
    foreach (SomeStruct s in structs)
    {
        item.SetSomeValue(30);
    }
    Debug.Log(structs[0].SomeValue); // prints 10
}

foreach is read-only but it works for classes because their reference is what becomes read-only, not the class itself. If you return a struct as ref you could open yourself up to something like this.

Note that if you wrote

item.SomeValue = 30;

in that foreach loop you would get a compiler exception.

http://www.tigranetworks.co.uk/blogs/electricdreams/the-evil-of-mutable-structs/

Hmm, I disagree. Strings for instance, are genuinely immutable:

string s = "hello world";
// there's no chance of modifying s
s[2] = 'i'; // doesn't compile

Whereas a Vector3 struct, is mutable

Vector3 v = new Vector3(1, 1, 1);
v.x = 10; // this indeed compiles.
Debug.Log(v); // outputs: (10,1,1)

Are you suggesting that the part v.x=10 is not modifying the struct?

Oh and I can’t even try your code because its throwing an exception.