Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Vector3 normalized vs Normalize()

Discussion in 'Scripting' started by rohunb, Oct 19, 2014.

  1. rohunb

    rohunb

    Joined:
    Jan 30, 2014
    Posts:
    20
    Does anyone know if the normalized property of a Vector3 is optimized to be pre-calculated in the constructor or something along those lines?

    Basically - is .normalized much more efficient that the Normalize() method (beyond the obvious of assignment operation where the vector itself is changed)
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    One of them returns a normalized value and the other one recalculates the vector (stores the value back in the vector), so it's more of a case of picking which one suits your code better than a speed issue. The speed hit is in the normalization of the vector, regardless if its stored after or you store it after. It shouldn't be any different in performance.

    So the answer is no.
     
  3. MariuszKowalczyk

    MariuszKowalczyk

    Joined:
    Nov 29, 2011
    Posts:
    301
    The topic is old, but I have tested this.
    If we have two vectors (Vector3), vec1 and vec2 then:
    - vec2.Normalize(); vec1 = vec2; is 10% faster than vec1 = vec2.normalized;
    - if these vectors are Vector2 then the first code is 20% faster.

    It may look like not much, but sometimes if you for example are programming a dedicated server physics, it may be worth using the faster code since it doesn't cost you anything.
     
    Tonymotion and BobberooniTooni like this.
  4. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    I guess it makes sense since the property is a shorthand form of this:

    Code (csharp):
    1.  
    2.  
    3. public Vector3 normalized
    4. {
    5.    get
    6.    {
    7.      return Vector3.Normalize(this);
    8.    }
    9. }
    10.  
    i.e. it also calls Normalize, but there's also the small overhead of creating a temporary Vector3 for the property to hand out.

    However, I'd like to see your numbers. 20% of what? Are we talking about fractions of a millisecond?

    Either way, if you're going to be calling normalize hundreds/thousands of times per frame to create a performance hit, maybe a better way to optimize this would be to avoid normalizing altogether (normalize once and cache it, or use sqrDistance instead where you can)
     
    Tonymotion likes this.
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    1) both of those code solutions are fundamentally different. the first ends up with both vec1 and vec2 being normalized, the other ends up with only vec1 being the normalized value.

    2) depends on the system you test it on. I tested it on my system and the speed difference between the 2 are actually really close, sometimes a being slightly faster than b, then other times b faster than a, averaging out to very close... if only leaning slightly in the favor of a (Normalize()).

    3) Rewriting a to be more appropriate and result in the behaviour of b you'd get this:
    Code (csharp):
    1.  
    2. vec1 = vec2;
    3. vec1.Normalize();
    4.  
    Oddly... on my machine... this performs ever so slightly faster than the other way around.
    Which only serves to show that the speeds are so darn close it's really hard to say.

    4) @BlackPete already pointed out the underlying behaviour of 'normalized'. But I had ran a test of that as well. And it actually ends up being the fastest of the lot consistently. Which makes sense since it has the fewest method calls, which is where most of the overhead is coming from.

    5) If you want to get super technical, you could even write your own custom normalize method and speed it up even more. This showed to be the fastest of them all (since we minimized method calls to a minimum):
    Code (csharp):
    1.  
    2.         public static Vector3 CustomNormalize(Vector3 v)
    3.         {
    4.             double m = System.Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
    5.             if (m > 9.99999974737875E-06)
    6.             {
    7.                 float fm = (float)m;
    8.                 v.x /= fm;
    9.                 v.y /= fm;
    10.                 v.z /= fm;
    11.                 return v;
    12.             }
    13.             else
    14.                 return Vector3.zero;
    15.         }
    16.  
    ...

    But I mean honestly......... this is just getting overkill at this point.
     
    Last edited: Dec 5, 2017