乐趣区

Unity C# Mathf.Abs()取绝对值性能测试

之前有人提到过取绝对值时 直接写三目运算符比用 Mathf.Abs()效率高 没觉得能高太多
今天测了一下 真是不测不知道 一测吓一跳 直接写三目运算符比 Mathf.Abs()效率高 2 - 3 倍

这性能差距有点不太合理啊!看下源码发现 很多 Mathf 的方法就是多封装了一层 Math 里的方法 把 double 型转成 float 型了 即便很简单得方法也没有重新实现
官方有点偷懒了 所以性能差距才会这么大 以后要求性能高的地方要注意 老老实实写一遍 能提升不少性能

ABS 效率对比

测试代码:

using UnityEngine;
using UnityEditor;
using System.Diagnostics;

/// <summary>
/// 执行时间测试
/// ZhangYu 2019-04-04
/// </summary>
public class TimeTest : MonoBehaviour {

    public int executeTimes = 1;
    private static Stopwatch watch;

    private void OnValidate() {times = executeTimes;}

    private static int times = 1;
    [MenuItem("CONTEXT/TimeTest/ 执行 ")]
    private static void Execute() {watch = new Stopwatch();

        // 数据
        float a = 1;

        // Mathf.Abs
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {a = Mathf.Abs(a);
        }
        watch.Stop();
        string msgMathfAbs = string.Format("Mathf.Abs: {0}s", watch.Elapsed);

        // 自己实现 Abs
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {a = MyAbs(a);
        }
        watch.Stop();
        string msgMyAbs = string.Format(" 自定义 Abs: {0}s", watch.Elapsed);

        // 三目运算符 Abs
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {a = a < 0 ? -a : a;}
        watch.Stop();
        string msg3Abs = string.Format(" 三目运算符 Abs: {0}s", watch.Elapsed);

        print(msgMathfAbs);
        print(msgMyAbs);
        print(msg3Abs);
    }

    // == 执行次数:10000000

    // Mathf.Abs
    // (1)0.2803558s
    // (2)0.2837749s
    // (3)0.2831089s
    // (4)0.2829929s
    // (5)0.2839846s

    // 自定义 Abs
    // (1)0.2162217s
    // (2)0.2103635s
    // (3)0.2103390s
    // (4)0.2092863s
    // (5)0.2097648s
    private static float MyAbs(float a) {return a < 0 ? -a : a;}

    // 三目运算符 Abs
    // (1)0.0893028s
    // (2)0.1000181s
    // (3)0.1017959s
    // (4)0.1001749s
    // (5)0.1005737s

}

Mathf.Abs()源码:

// Returns the absolute value of /f/.
public static float Abs(float f) {return (float)Math.Abs(f); }

// Returns the absolute value of /value/.
public static int Abs(int value) {return Math.Abs(value); }

官方 Mathf 部分源码:

Mathf 部分源码 1
Mathf 部分源码 2
退出移动版