Search Unity

Slow Unity Math. Please Unity Tech., keep core math fast

Discussion in 'Scripting' started by half_voxel, Oct 8, 2013.

  1. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    I have posted similar threads before when I have found deficiencies in core math in Unity (like Mathf).
    Here is another one.
    According to the monodevelop .dll reflector, this is the implementation for Bounds.Intersect

    Code (csharp):
    1. using System;
    2. public bool Intersects (Bounds bounds)
    3. {
    4.     return this.min.x <= bounds.max.x  this.max.x >= bounds.min.x  this.min.y <= bounds.max.y  this.max.y >= bounds.min.y  this.min.z <= bounds.max.z  this.max.z >= bounds.min.z;
    5. }
    Note that it gets bounds.max and min A LOT. These are properties which involve a Vector3 addition. So this piece of code currently uses 36 additions and also 12 copies of Vector3's (properties must return copies). Also the fact that it calls properties is in itself overhead at least on 32bit (64bit mono does seem to optimize for that better, only a very very small overhead compared to direct field access). It could use only 12 additions and no copies or property accesses if implemented correctly. Also, I doubt the JIT is smart enough to optimize this, it would have to figure out that it is only using the .x (or .y or .z) field, and then track the addition operator and see that it actually only need to add the .x fields to get the resulting .x field. Especially since the JIT doesn't even properly inline simple getter properties in 32bit (including the unity editor).

    I am noting this here because when profiling, I found that Bounds.Intersect took 2.2% of the CPU time, an unreasonably high percentage for what it was doing.

    Also, the Bounds.max and min getters in turn call the center and extents properties, not the fields, even though the code has access to those private fields. On 32bit (and in the unity editor) this will cause slowdowns.
    Bounds.size is however well behaved and uses the fields directly.

    Please Unity guys, fix these kinds of things in the API.

    Unity Version: 4.2.0b4
    Operating System: OS X (10.7.4)


    [EDIT]

    Profiling it, it seems like I can with very simple code, make it run 30% faster.
    Code (csharp):
    1. private bool Intersects (Bounds b1, Bounds b2)        {
    2.             Vector3 min1 = b1.min;
    3.             Vector3 max1 = b1.max;
    4.             Vector3 min2 = b2.min;
    5.             Vector3 max2 = b2.max;
    6.             return min1.x <= max2.x  max1.x >= min2.x  min1.y <= max2.y  max1.y >= min2.y  min1.z <= max2.z  max1.z >= min2.z;
    7.         }
    Even though the above code has several things slowing it down. It needs to take another parameter, which requires a 24 byte copy of the struct, and it must store the max and min values as variables instead of calculating them directly in the expression since it does not have direct access to the fields. Also it must use the getters for the min and max values for the same reason.

    U bounds 3085.2 ms avg: 308.52 ms avg mem: 0 bytes
    U2 bounds 2193.8 ms avg: 219.38 ms avg mem: 0 bytes

    Profiling code: http://pastebin.com/VuxiEecA
    The Profile class simply holds a System.Diagnostics.Stopwatch and also queries System.GC for the memory usage.
     
    Last edited: Oct 31, 2013
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I recall Unity asking the community for instances where their own Math was slower like Lerp etc so they could improve this situation.
     
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
  4. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    I was just reading more about this the other day .. I can understand some benefits of value data types but what is the point if every time you need to access the value then it gets duplicated over and over and over.. when no values are even been set .. only read..?
     
  5. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Just make the fields public and move on in life .. I would not even care if every OOP language in the world made getters and setters obsolete , in fact I would be happy.

    They are mostly used without any additional validation or logic to set one "private" field .. when ever I see code like this I ask myself .. what is the point here? You obeyed some mythical convention of encapsulation which served no purpose.

    To all those who do this.. break free from the chains of Dogma .. declare a public field and feel the freedom ;) hehe
     
  6. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
  7. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    The Dogma is strong with this one @exiguous
     
  8. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    I agree that skipping properties is what you should do if it is just backing a field. Except when you want to expose it as read only for the rest of the world but writable by your class.

    The min and max properties in the Bounds are however totally valid. The Bounds is defined by its center and extents, not by its min and max values.
     
  9. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    the link was simply an answer to your comment where you ask why to use it. the author lists some usecases for properties. so they are not that useless if used properly. and i think some people would be annoyed when they are removed as you suggested. everyone can decide for her/himself wether the advantages are worth the effort. and especially coders who are payed by lines of code will be happy about them ;).
     
  10. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    No worries exiguous I was just stirring the pot ;)

    Tower of bricks ,the Bounds constructor uses center and extents but the class also has a method named SetMinMax() which obviously alters the extends so really its defined by one or the other . . Ive recently written some code that uses bounds and at the time some how convinced myself that min / max were fields ;(
     
  11. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    What I mean is that internally the Bounds struct uses the fields m_Center and m_Extents, so it is internally defined by the center and extents. Of course it can mathematically be defined in a huge number of ways.
     
  12. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    While we're arguing:

    I tend to appreciate properties when used with middleware such as 2D Toolkit. This means I can change .color of a sprite in a unity-familiar and friendly workflow, and the sprite will only resubmit the mesh colors + additional work on changes. It's small things like this which make middleware a pleasure to use over sprite.SetColor(thing);

    Generally (let's be realistic) - most people will not see any benefit from using properties within Unity on their own games. A field offers a much easier coding path. If you want to use properties it should be because you a) enjoy the coding pattern of changing a property and it performs additional funcrions or b) you're doing middleware.

    Using it blindly for everything within a Unity only context is probably going to be pointless. I bet everyone who discovered properties used them everywhere initially then realised it probably wasn't the best fit for everything. As always, use things wisely when they're needed :)
     
  13. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    I like to use properties to write stable code, especially when writing code that others will use.

    Instead of making a bool named isVisible, which should always be synced to if some object is visible on the screen, I make it a property so that every time it is changed, it will set the visibility of that other object. Then there is no possibility of them getting out of sync by for a user assigning the isVisible field without updating the visibility of the object.
     
  14. XGundam05

    XGundam05

    Joined:
    Mar 29, 2012
    Posts:
    473
    Not to derail this even further...but to derail this even further:

    A wise person once told me: "Write your code as if a murderous psychopath who knew where you lived was going to use/maintain it". So yeah, to echo others, Properties are great for event-driven stuff and middleware. They're also good for making easily extensible classes.

    [Edit:] again, echoing -.- [/Edit] They are not, however, so good for performance critical code. If the property isn't able to be in-lined, the overhead of an additional function call can be killer (XNA was terrible with this on the XBox...it never seemed to in-line anything -.-)

    Anywho....
     
    Last edited: Nov 1, 2013
  15. half_voxel

    half_voxel

    Joined:
    Oct 20, 2007
    Posts:
    978
    I investigated property inlining more in this post: http://forum.unity3d.com/threads/207254-How-much-faster-would-Unity-games-apps-be-if-it-used-C/page5
    Simple getters seem to be inlined at least on 64-bit.