数学运算比IF要快
问题
虽然很早就知道,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要快的更多相关文章
- PHP - 数学运算
第4章 数学运算 学习要点: 1.数值数据类型 2.随机数 3.格式化数据 4.数学函数 在大多数程序设计语言中,数值运算都是最基本的元素之一.数值运算允许程序员完成加法到高级计算等各种操作.尽管PH ...
- Unity3D中Mathf数学运算函数总结
引入: 看到一个案例注意到函数Mathf.SmoothDamp的使用,游戏中用于做相机的缓冲跟踪和boss直升机跟踪士兵.该函数是Unity3D中Mathf数学运算函数中的一个.一些游戏使用了smoo ...
- Python之复数、分数、大型数组数学运算(complex、cmath、numpy、fractions)
一.复数的数学运算 复数可以用使用函数 complex(real, imag) 或者是带有后缀j的浮点数来指定 a=complex(2,4) print(a) # (2+4j) b=2-5j # 获取 ...
- Java学习笔记 06 数字格式化及数学运算
一.数字格式化 DecimalFormat类 >>DecimalFormat是NumberFormat的子类,用于格式化十进制数,可以将一些数字格式化为整数.浮点数.百分数等.通过使用该类 ...
- 从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)
1.server端 支持数学运算的服务器,服务器的返回结果用json对象表示. math-server.js //通过监听3000端口使其作为Math Wizard的后台程序 var math = r ...
- Linux shell 变量 数学 运算
Abstract : 1) Linux shell 中使用 let , [ ] ,(( )) 三种运算符操作 shell 变量进行简单的基本运算: 2)Linux shell 中使用 expr 与 ...
- 认真学习shell的第一天-数学运算
shell中的数学运算有三种方式: (1)let,用let的时候,变量名称前不用添加$ (2)[],[]中变量可使用也可不使用$ (3)(())变量名之前必须添加$
- 6 让我们的C#程序开始做点数学运算
请相信我你只需要懂得最基本的数学运算,就可以从事大多数的软件项目的开发工作.千万不要一提编程,就让数学把你吓跑了.大多数的程序开发人员从事的编程工作是应用系统的开发.这些系统的绝大多数功能,只需要最基 ...
- shell编程之数学运算
shell数学运算支持整数运算的四种方法 1.let命令 no1=4; no2=5; let result=no1+no2 2.[]操作符 result=$[ no1 + no2] 3.(())操作符 ...
随机推荐
- Git 教程(二):提交和回退
我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容: Git is a distributed version c ...
- spring源码解析2--容器的基本实现
spring的主要特性是IOC,实现IOC的关键是bean,而更关键的是如何bean的管理容器,也就是BeanFactory,本文的目标是弄清楚BeanFactory具体是怎么样的存在. 先看下最简单 ...
- Python strip()与lstrip()、rstrip()
.strip()方法可以根据条件遍历字符串中的字符并一一去除 默认去除字符串中的头尾空格 “ Alins ”.“ AA BB CC ”用了之后就是 “Alins”.“AA BB CC” ...
- [dart学习]第一篇:windows下安装配置dart编译环境,写出helloworld
前言 博主非科班出身,平时多用C语言,最近想了解学习一门第二语言,看上了可用于移动开发的目前还小众一点dart,准备用一段比较长的时间来慢慢学习.理解. 关于dart语言不再详细介绍了,大家可以访问 ...
- 创建作业(JOB)
在SQL Server日常需求处理中,会遇到定时执行或统计数据的需求,这时我们可以通过作业(JOB)来处理,从而通过代理的方式来实现数据的自动处理.一下为SQL Server中创建作业的脚本,供大家参 ...
- 让selenium中的Cromerderive不加载图片设置
把配置参数(chrom_opt)设置好后将其添加到 browser = webdriver.Chrome(executable_path="chromedriver.exe的路径" ...
- Kali Linux Xfce版美化虚拟机镜像
起因 这两天来学校把硬盘基本全部清空了,所以以前的虚拟机就需要重新安装了. Kali 一直用的是 xfce 版本,至于为什么用这个版本,是因为我感觉 gnome3 在虚拟机上表现欠佳.当然,默认的 g ...
- git忽略对已入库文件的修改
项目开发过程中,会遇到本地配置文件每个开发人员不同的情况,但如果遇到类似数据库配置这种最终需要加入 git 版本控制的配置,则会陷入两难境地.要么不跟踪,要么有人提交后其他人同步下来必须手动修改,非常 ...
- 比原链(Bytom)先知节点 Ubuntu接入文档
系统要求 我们建议选择知名的VPS服务商,运行比原链节点对算力没有要求,但是请配置尽可能大的磁盘空间. 节点服务器最小配置: 操作系统: Windows/Linux/Docker CPU: 2核 内存 ...
- Gridview标题头添加排序图片
向gridview标题头中添加排序图片,当点击某一个头标题时,在标题中出现升序箭头向上的图片,再点击一次时降序,在标题中出现箭头向下的图片,初始页面时在标题头中并不现实任何图片. 先定义好一个grid ...