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

这性能差距有点不太合理啊! 看下源码发现 很多Mathf的方法就是多封装了一层Math里的方法 把double型转成float型了,而看了C#源码发现Abs里有一些对错误数据的判断处理,比如检查值是溢出,如果溢出会抛出异常等(比如int.MinValue无法取到对应的正整数,数据溢出了)。多了一些判断语句和方法调用,效率自然比直接写代码要低了。
以后要求性能高的地方要注意,老老实实写一遍,能提升不少性能。当然,你要保证数值不会溢出。

Mathf.Abs(v)
v = v < 0 ? -v : v
if (v < 0) v = -v
// 这三种取绝对值写法中 if判断负数 效率最高

Abs效率对比

测试代码:

    // times = 100000000
    // 1亿次 ( >=0时 2980ms) ( <0时 2993ms)
    private void AbsTest0(float v) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            float f = v;
            f = Mathf.Abs(f);
        }
        watch.Stop();
        Log("AbsTest0 Mathf.Abs(f):" + watch.ElapsedMilliseconds + "ms");
    }

    // 1亿次 ( >=0时 1123ms 比1快165.4%) ( <0时 1153ms 比1快159.6%)
    private void AbsTest1(float v) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            float f = v;
            f = f < 0 ? -f : f;
        }
        watch.Stop();
        Log("AbsTest1 三目运算:" + watch.ElapsedMilliseconds + "ms");
    }

    // 1亿次 ( >= 0时 950ms 18.2%) ( <0时 1094ms 比1快5.4%)
    private void AbsTest2(float v) {
        watch.Reset();
        watch.Start();
        for (int i = 0; i < times; i++) {
            float f = v;
            if (f < 0) f = -f;
        }
        watch.Stop();
        Log("AbsTest2 if(v < 0):" + watch.ElapsedMilliseconds + "ms");
    }

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

更高性能取绝对值方法:
https://blog.csdn.net/qq_1507...


冰封百度
233 声望43 粉丝

Unity游戏程序员一枚。生命不息,学习不止。