这才是这个世界上求绝对值最快的方法,温故知新。

前言

今天偶然翻到很久以前发的一条说说,可谓如获至宝啊!!!

涉及到返回一个数的绝对值,最快的方法是:

for (int i = 0; i < loops; i++)
{
    for (int j = 0; j < 65535; j++)
    {
         tmp = array[j] * (1 - (array[j] >> 31) << 1);
    }
}

测试

按道理说,语句里有乘法,应该会降低执行效率,可是不可思议的是,这个弱点被位移操作弥补了!!!
然而我不淡定了,我必须得测试下:

            Console.WriteLine("To start press any key");
            Console.ReadKey();
            int[] array = new int[65535];
            long[] counters = new long[3];
            long ts = 0, dtstart = 0, freq = 0;
            int tmp = 0, loops = 5000;
            QueryPerformanceFrequency(ref freq);
            #region generate
            for (int i = 0; i < 65535; i++)
            {
                array[i] = i - 32768;
            }
            #endregion
            QueryPerformanceCounter(ref dtstart);
            #region RL RR
            for (int i = 0; i < loops; i++)
            {
                for (int j = 0; j < 65535; j++)
                {
                    tmp = array[j] * (1 - (int)((((uint)array[j]) >> 31) << 1));
                }
            }
            #endregion
            QueryPerformanceCounter(ref ts);
            counters[0] = ts - dtstart;
            QueryPerformanceCounter(ref dtstart);
            #region triitem
            for (int i = 0; i < loops; i++)
            {
                for (int j = 0; j < 65535; j++)
                {

                    tmp = array[j] < 0 ? -array[j] : array[j];
                }
            }
            #endregion
            QueryPerformanceCounter(ref ts);
            counters[1] = ts - dtstart;
            QueryPerformanceCounter(ref dtstart);
            #region ifcase
            for (int i = 0; i < loops; i++)
            {
                for (int j = 0; j < 65535; j++)
                {
                    if (array[j] < 0)
                    {
                        tmp = -array[j];
                    }
                    else
                    {
                        tmp = array[j];
                    }
                }
            }
            #endregion
            QueryPerformanceCounter(ref ts);
            counters[2] = ts - dtstart;

            Console.WriteLine("Three Methods cost {0}ms {1}ms {2}ms, respectively!", 1000 * counters[0] / freq, 1000 * counters[1] / freq, 1000 * counters[2] / freq);
            Console.WriteLine("To end press any key");
            Console.ReadKey();

输出结果

Three Methods cost 185ms 176ms 185ms, respectively, when loops=500!

Three Methods cost 330ms 364ms 367ms, respectively, when loops=1000!

Three Methods cost 1638ms 1822ms 1827ms, respectively, when loops=5000!

Three Methods cost 3221ms 3700ms 3669ms, respectively, when loops=10000!

Three Methods cost 16249ms 18901ms 20479ms, respectively, when loops=50000!

不要怀疑这个结果!!因为我把代码块的位置调换了几次结论都是一样的!


结论

可见,这种针对机器码优化过的代码效率很高,那么,将乘法直接改成位操作不是更快吗?

答案是不行,因为绝对值相同的正负数其数值部分的位态是不一样的。

另一个可以得出的结论是,三目的效率与if分支相当。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值