Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411490 Posts in 69371 Topics- by 58428 Members - Latest Member: shelton786

April 24, 2024, 05:29:11 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Unity's prolific getter / setters
Pages: [1]
Print
Author Topic: Unity's prolific getter / setters  (Read 1400 times)
st33d
Level 2
**



View Profile WWW
« on: January 22, 2017, 03:23:19 AM »

I'm writing a spatial hash for a lot of bullets to use. This will involve registering each bullet with the hash and updating it when its bounds move over new cells. Simple right? Should save me some cpu when I have thousands of the buggers flying (bullets may be able to hit bullets after all).

The 1st problem I encounter is Unity's approach to getter setters, they're just slower:

Code:
using UnityEngine;
using System.Collections;
using System.Diagnostics;

public class BenchTest : MonoBehaviour {

public static void Go() {
Rek r1 = new Rek(0, 0, 1, 1);
Rect r2 = new Rect(0, 0, 1, 1);

Stopwatch s = new Stopwatch();

s.Start();
for(int i = 0; i < 1000000; i++) {
r1.x += 1;
}
s.Stop();
UnityEngine.Debug.Log(s.ElapsedMilliseconds);

s.Reset();

s.Start();
for(int i = 0; i < 1000000; i++) {
r2.x += 1;
}
s.Stop();
UnityEngine.Debug.Log(s.ElapsedMilliseconds);
}

public struct Rek {
public float x, y, width, height;
public Rek(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}

}

Code:
6
18

I know this is nitpicking really. But this is some core loop stuff that I'm writing for the purpose of optimisation - I'm going to be accessing these variables a LOT. It's kinda simple to work with Rects and then just swap them out I guess.

What do you do in this situation. Put up with Unity's slow code? Completely roll your own? Maybe it's a half and half deal. I'm interested to hear what other people's thoughts are.
Logged
oahda
Level 10
*****



View Profile
« Reply #1 on: January 22, 2017, 04:49:30 AM »

D: Good to know. Does the latest version of C# in general have this issue too, or is it just the old one Unity is stuck with? Would've expected uncustomised getters and setters to be inlined and identical to working directly with the variables...

If rectangles are the only, or one of the few, structs you need to be working with, and performance matters, it doesn't seem unreasonable to me to roll your own in this case. Especially for something so easy to implement.
Logged

bateleur
Level 10
*****



View Profile
« Reply #2 on: January 23, 2017, 04:21:57 AM »

What do you do in this situation. Put up with Unity's slow code? Completely roll your own?

I roll my own if and only if I need the higher performance. Which is basically never for me, but I might in your case.

Incidentally, "slow code" might be unfair in this case. If Unity is updating the value of stuff like Rect.width as part of the call, this could account for the performance difference. (With eager-vs-lazy updating of this kind of field being a tradeoff. When writing a general purpose library you never know which would be better for the user.)
Logged

st33d
Level 2
**



View Profile WWW
« Reply #3 on: January 23, 2017, 04:50:05 AM »

If Unity is updating the value of stuff like Rect.width as part of the call, this could account for the performance difference.

Nope.

I wrote a new struct with a getter/setter for x to test your theory. It's just as slow. In fact, on OSX (my work machine) both Rect and the new struct are even slower (33ms instead of 18ms). And yes, I've changed the order of execution to double check the results.

With an auto-implemented get/set it shaves off only 4ms. The problem is the method call, that's what is slow. The reason Unity has a policy for using getter/setters for everything is of course down to maintenance. Who knows what internal changes they will have to make in future.

In this instance it is a bit silly though.
Logged
bateleur
Level 10
*****



View Profile
« Reply #4 on: January 23, 2017, 08:01:59 AM »

The reason Unity has a policy for using getter/setters for everything is of course down to maintenance. Who knows what internal changes they will have to make in future.

Sorry, I don't quite follow. Surely changes made by Unity themselves would be part of a new version and therefore there'd be no problems anyway? Isn't the whole point that getters/setters mimic field access flawlessly?

(Good job on doing the test, though. Real data FTW!)
Logged

cavalierro
Level 0
**


Gentle Coder


View Profile
« Reply #5 on: February 08, 2017, 07:24:03 PM »

st33d, I looked into it a bit, second that this is a standard speed difference between accessing member variable and acessing a property (similar to a function call).

Also, not sure if it's implemented in the x property or the xMax property, but in Unity's Rect, modifying x modifies xMax as well, which you probably don't need in your actual Rek structure.

Code:
Rect aurus = new Rect(0, 0, 1, 1);
Debug.LogFormat("{0}-{1}", aurus.xMin, aurus.xMax);
aurus.x += 1;
Debug.LogFormat("{0}-{1}", aurus.xMin, aurus.xMax);
gives
Code:
0-1
1-2
Logged

I'm having a quarantine party this weekend and none of you are invited.

(/r/oneliners)
st33d
Level 2
**



View Profile WWW
« Reply #6 on: February 09, 2017, 05:43:53 AM »

in Unity's Rect, modifying x modifies xMax as well

x, xMax, width are all getter/setters.

If you hover over those properties in MonoDevelop it tells you their nature.

It is more likely that xMax calls a function returning x+width. If there was an internal value for xMax, or any of the other values then the memory required for passing a Rect would be much larger.

Rect is a struct, so that means a copy of it is created whenever it is referred to. So giving it extra properties that could be reduced to function calls is quite a stupid move, especially when all of the properties can only be accessed by calling a function.
Logged
Richard Kain
Level 10
*****



View Profile WWW
« Reply #7 on: February 09, 2017, 12:56:51 PM »

MonoBehaviors are not designed with getters/setters in mind. The official Unity documentation in particular strongly recommends avoiding their use. Public and private properties are the way to go for this kind of functionality.

Of course, all of this applies to MonoBehaviors in particular. If you are creating your own base classes, and not extending from Monobehavior, I would imagine things would be different. Have you tried experimenting with that?

Whenever I have specific data-focused classes, I usually create them by themselves and don't extend from MonoBehavior. While I avoid using getters/setters in MonoBehavior scripts, I have no fear of using them in my own data classes. It could be that there is no difference in performance, but I would give it a look-see.
Logged
st33d
Level 2
**



View Profile WWW
« Reply #8 on: February 10, 2017, 08:13:37 AM »

MonoBehaviors are not designed with getters/setters in mind. The official Unity documentation in particular strongly recommends avoiding their use. Public and private properties are the way to go for this kind of functionality.

Of course, all of this applies to MonoBehaviors in particular.

What's Monobehaviors got to do with any of this? Rect is derived from System.ValueType by virtue of being a struct. It has nothing to do with Monobehavior and I never mentioned Monobehavior before this post. Perhaps you read my mentioning of Monodevelop the coding IDE and assumed I was talking about components (which are derived from Monobehavior).

I was asking about personal preference in using Unity's structs, or whether you roll your own.

It's not as consistent as I first suggested either. Vector3's properties can be accessed directly - there is no prompt from Monodevelop about getter / setters being used.
Logged
Richard Kain
Level 10
*****



View Profile WWW
« Reply #9 on: February 10, 2017, 09:39:19 AM »

Ah yes, I see the Rek class's definition now. (had to scroll down a little) Although this just raises more questions. It doesn't look like Rek has any getters/setters. It just has public properties, which aren't the same thing. Where are the getters/setters you were mentioning? Are you referring perhaps, to the arguments that you are using in Rek's constructor?
Logged
st33d
Level 2
**



View Profile WWW
« Reply #10 on: February 13, 2017, 03:03:07 AM »

I was referring to the Rect struct in Unity. I mentioned it in the 1st post. The Rek struct I've included in the code example is there to demonstrate that properties are faster to access and that Unity's Rect does indeed use getter / setters.

I'm providing empirical evidence before people start giving me opinions on the matter. That is why the code sample is there. Sorry to have confused you but I assumed that if you read the post that this would be obvious.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic