Floats are slower than Doubles :O

Not really - they perform at the same speed on a 64 bit platform but Unity uses a math library for doubles and casts to and from doubles to return and accept floats. Here’s the source I found with assembly browser:

amespace UnityEngine
{
    public struct Mathf
    {
        //
        // Static Fields
        //
        public const float Deg2Rad = 0.0174532924f;

        public const float Rad2Deg = 57.29578f;

        public static readonly float Epsilon;

        public const float PI = 3.14159274f;

        public const float Infinity = float.PositiveInfinity;

        public const float NegativeInfinity = float.NegativeInfinity;

        //
        // Static Methods
        //
        public static float Abs (float f)
        {
            return Math.Abs (f);
        }

        public static int Abs (int value)
        {
            return Math.Abs (value);
        }

        public static float Acos (float f)
        {
            return (float)Math.Acos ((double)f);
        }

        public static bool Approximately (float a, float b)
        {
            return Mathf.Abs (b - a) < Mathf.Max (1E-06f * Mathf.Max (Mathf.Abs (a), Mathf.Abs (b)), Mathf.Epsilon * 8f);
        }

        public static float Asin (float f)
        {
            return (float)Math.Asin ((double)f);
        }

        public static float Atan (float f)
        {
            return (float)Math.Atan ((double)f);
        }

        public static float Atan2 (float y, float x)
        {
            return (float)Math.Atan2 ((double)y, (double)x);
        }

        public static float Ceil (float f)
        {
            return (float)Math.Ceiling ((double)f);
        }

        public static int CeilToInt (float f)
        {
            return (int)Math.Ceiling ((double)f);
        }

        public static float Clamp (float value, float min, float max)
        {
            if (value < min)
            {
                value = min;
            }
            else
            {
                if (value > max)
                {
                    value = max;
                }
            }
            return value;
        }

        public static int Clamp (int value, int min, int max)
        {
            if (value < min)
            {
                value = min;
            }
            else
            {
                if (value > max)
                {
                    value = max;
                }
            }
            return value;
        }

        public static float Clamp01 (float value)
        {
            if (value < 0f)
            {
                return 0f;
            }
            if (value > 1f)
            {
                return 1f;
            }
            return value;
        }

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern int ClosestPowerOfTwo (int value);

        public static float Cos (float f)
        {
            return (float)Math.Cos ((double)f);
        }

        public static float DeltaAngle (float current, float target)
        {
            float num = Mathf.Repeat (target - current, 360f);
            if (num > 180f)
            {
                num -= 360f;
            }
            return num;
        }

        public static float Exp (float power)
        {
            return (float)Math.Exp ((double)power);
        }

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern ushort FloatToHalf (float val);

        public static float Floor (float f)
        {
            return (float)Math.Floor ((double)f);
        }

        public static int FloorToInt (float f)
        {
            return (int)Math.Floor ((double)f);
        }

        public static float Gamma (float value, float absmax, float gamma)
        {
            bool flag = false;
            if (value < 0f)
            {
                flag = true;
            }
            float num = Mathf.Abs (value);
            if (num > absmax)
            {
                return (!flag) ? num : (-num);
            }
            float num2 = Mathf.Pow (num / absmax, gamma) * absmax;
            return (!flag) ? num2 : (-num2);
        }

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern float GammaToLinearSpace (float value);

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern float HalfToFloat (ushort val);

        public static float InverseLerp (float a, float b, float value)
        {
            if (a != b)
            {
                return Mathf.Clamp01 ((value - a) / (b - a));
            }
            return 0f;
        }

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern bool IsPowerOfTwo (int value);

        public static float Lerp (float a, float b, float t)
        {
            return a + (b - a) * Mathf.Clamp01 (t);
        }

        public static float LerpAngle (float a, float b, float t)
        {
            float num = Mathf.Repeat (b - a, 360f);
            if (num > 180f)
            {
                num -= 360f;
            }
            return a + num * Mathf.Clamp01 (t);
        }

        public static float LerpUnclamped (float a, float b, float t)
        {
            return a + (b - a) * t;
        }

        [WrapperlessIcall]
        [MethodImpl (MethodImplOptions.InternalCall)]
        public static extern float LinearToGammaSpace (float value);

        public static float Log (float f)
        {
            return (float)Math.Log ((double)f);
        }

        public static float Log (float f, float p)
        {
            return (float)Math.Log ((double)f, (double)p);
        }

        public static float Log10 (float f)
        {
            return (float)Math.Log10 ((double)f);
        }

        //You get the point
    }
}

What does this mean? Not anything really. The casting is negligible compared to the cost of the transcendental functions Unity wrapped up and the smaller lines of code you have to write are definitely worth it. Just wanted to point out that you’re doing calculations with doubles when you use the Mathf library.

Haha, Well good to know! I’ve kinda just neglected learning which basic types are faster than others, as I was under the assumption with current computing power I can’t imagine it impacting your end result at all.

That’s not true.
It does have an effect. What it comes down to is whether the performance impact is negligible or not. That pretty much depends on what exactly you’re doing.

1 Like

This is good to know. There’s a lot of disregard for the smaller things when it comes to performance, but not everyone is making small games. I have code that will likely need to run millions of times. When code is running millions of times, you have to care about the small things because it adds up fast.

2 Likes

Keep in mind I haven’t made anything larger than a mobile game yet.

That’s odd. The scripting reference clearly says all Mathf functions take floats, meaning that if you use doubles it would just cast them to floats. I doubt the devs would leave out if the functions actually used doubles.
Either way if there was a place in code where performance was critical I would have used my own functions anyway.

1 Like

The cost of casting from double to float is comparable to a += operation. 2 extra +=s won’t kill your code. To put it into perspective, calling a virtual function is slower than 2 +=s. And you probably won’t write significantly faster algorithms than the ones in the System.Math library.

Yeah, certainly if you’re worried about performance there would be many higher priorities. I just want every last thing performing very well in those critical sections.

1 Like