问题

虽然很早就知道,CPU在处理 if 这样的判断语句时,使用了预测的技术,所以如果条件总是一个结果,效率就很好。反过来说,如果你使用数学运算避免 if 判断,那么就意味着性能一定比 if 要好。

方案1

今天正好有个函数遇到这个问题,所以我就正好测试以下。

待测试的方法是获取一个int32的数据中,有多少个位是 1,我的方案是将 一个int32拆开成 4个字节,然后一一判断。下面是使用 if 判断的方案 (那个  ? : 三元运算符就是 if 语句)。

 static int getInt32TrueCount(int value)
{
if (value == )
{
return ;
} return getByteTrueCount(value & 0xFF) +
getByteTrueCount((value >> ) & 0xFF) +
getByteTrueCount((value >> ) & 0xFF) +
getByteTrueCount((value >> ) & 0xFF);
} static int getByteTrueCount(int value)
{
if (value == )
{
return ;
} int a = (value & 0x1) == ? : ;
int b = (value & 0x2) == ? : ;
int c = (value & 0x4) == ? : ;
int d = (value & 0x8) == ? : ; int e = (value & 0x10) == ? : ;
int f = (value & 0x20) == ? : ;
int g = (value & 0x40) == ? : ;
int h = (value & 0x80) == ? : ; return a + b + c + d + e + f + g + h;
}

可以看到, 每运算一个位都有一个 if 判断,而要命的是这个 if 判断的结果是不稳定的,随机性极大。我写了一个计时程序,在我计算机中需要 12秒。(i5 6500 Release .net core 2.0 )

 static void GetBitCountTest()
{
var wathch = Stopwatch.StartNew(); var rand = new Random(); for (int i = ; i < 10000_0000; i++)
{
int value = rand.Next();
int p = getInt32TrueCount(value);
} wathch.Stop();
Console.WriteLine("GetBitCount 耗时:" + wathch.Elapsed.ToString()); }

方案2

第二种方法就是将 if 判断改为数学运算,方法是将 and 运算后的位 移动到 0位,这样就是 0 或 1 了。

 static int getInt32TrueCount2(int value) {
if (value == ) {
return ;
} return getByteTrueCount2(value & 0xFF) +
getByteTrueCount2((value >> ) & 0xFF) +
getByteTrueCount2((value >> ) & 0xFF) +
getByteTrueCount2((value >> ) & 0xFF);
} static int getByteTrueCount2(int value) {
return (value & 0x1) +
((value & 0x2) >> ) +
((value & 0x4) >> ) +
((value & 0x8) >> ) + ((value & 0x10) >> ) +
((value & 0x20) >> ) +
((value & 0x40) >> ) +
((value & 0x80) >> );
}

再次运行测试用例,执行时间提高到 2 秒!提高了6倍。

总结:

高性能计算时,避免使用 分支 指令,尽量使用数学运算符。

数学运算比IF要快的更多相关文章

  1. PHP - 数学运算

    第4章 数学运算 学习要点: 1.数值数据类型 2.随机数 3.格式化数据 4.数学函数 在大多数程序设计语言中,数值运算都是最基本的元素之一.数值运算允许程序员完成加法到高级计算等各种操作.尽管PH ...

  2. Unity3D中Mathf数学运算函数总结

    引入: 看到一个案例注意到函数Mathf.SmoothDamp的使用,游戏中用于做相机的缓冲跟踪和boss直升机跟踪士兵.该函数是Unity3D中Mathf数学运算函数中的一个.一些游戏使用了smoo ...

  3. Python之复数、分数、大型数组数学运算(complex、cmath、numpy、fractions)

    一.复数的数学运算 复数可以用使用函数 complex(real, imag) 或者是带有后缀j的浮点数来指定 a=complex(2,4) print(a) # (2+4j) b=2-5j # 获取 ...

  4. Java学习笔记 06 数字格式化及数学运算

    一.数字格式化 DecimalFormat类 >>DecimalFormat是NumberFormat的子类,用于格式化十进制数,可以将一些数字格式化为整数.浮点数.百分数等.通过使用该类 ...

  5. 从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)

    1.server端 支持数学运算的服务器,服务器的返回结果用json对象表示. math-server.js //通过监听3000端口使其作为Math Wizard的后台程序 var math = r ...

  6. Linux shell 变量 数学 运算

    Abstract : 1)  Linux shell 中使用 let , [ ] ,(( )) 三种运算符操作 shell 变量进行简单的基本运算: 2)Linux shell 中使用 expr 与 ...

  7. 认真学习shell的第一天-数学运算

    shell中的数学运算有三种方式: (1)let,用let的时候,变量名称前不用添加$ (2)[],[]中变量可使用也可不使用$ (3)(())变量名之前必须添加$

  8. 6 让我们的C#程序开始做点数学运算

    请相信我你只需要懂得最基本的数学运算,就可以从事大多数的软件项目的开发工作.千万不要一提编程,就让数学把你吓跑了.大多数的程序开发人员从事的编程工作是应用系统的开发.这些系统的绝大多数功能,只需要最基 ...

  9. shell编程之数学运算

    shell数学运算支持整数运算的四种方法 1.let命令 no1=4; no2=5; let result=no1+no2 2.[]操作符 result=$[ no1 + no2] 3.(())操作符 ...

随机推荐

  1. centos6.5 MySQL数据库的安装

    <div id="home"><div id="header"> <div id="blogTitle"> ...

  2. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  3. 画多边形form并填充背景色(可以实现圆角边框 有锯齿)

    public Form1() { InitializeComponent(); this.BackColor = ColorTranslator.FromHtml("#F7F1F1" ...

  4. 推荐!PlayGround:可视化神经网络

    https://cloud.tencent.com/developer/news/190352 http://playground.tensorflow.org PlayGround是一个在线演示.实 ...

  5. P2774 方格取数问题(网络流)

    P2774 方格取数问题 emm........仔细一看,这不是最大权闭合子图的题吗! 取一个点$(x,y)$,限制条件是同时取$(x,y+1),(x,y-1),(x+1,y),(x-1,y)$,只不 ...

  6. STM32时钟

    https://blog.csdn.net/qq_29350001/article/details/81409693 这是个大佬讲的 F429有5个时钟源,HSI,HSE,LSI,LSE;PLL; 对 ...

  7. Python游戏编程入门

    <Python游戏编程入门>这些文章负责整理在这本书中的知识点.注意事项和课后习题的尝试实现.并且对每一个章节给出的最终实例进行分析和注释. 初识pygame:pie游戏pygame游戏库 ...

  8. 【BUAA-OO】第一单元作业总结

    #OO第一单元作业总结 #确认存活,爱学习,爱北航,爱OO 一.三次作业分析 1.第一次作业 1.1 程序结构 对方法的度量: 类的内聚和相互间的耦合情况: 类图: 优缺点: 优点大概没什么优点,毕竟 ...

  9. IP包设计

    IP包 IP核(Intellectual Property core)就是知识产权核或知识产权模块的意思,用于配置FPGA或其它硅芯片上的逻辑资源. 引用链接https://blog.csdn.net ...

  10. HTML5 API分享

    Facebook - http://developers.facebook.com/ 人人网开放平台 - http://dev.renren.com/ 51.com开放平台 - http://deve ...