先上结论

模运算运算慢20%到30%

这是通过实验的方式得到的结论.因为没有大大可以进行明确指导,所以我以最终运行的结果为准.欢迎指正.

测试代码

@Test
public void test10() {
int a, b, temp, count = 100000000;
long start, time; Random random = new Random(); while (true) {
System.out.println("-----------------------------------------------");
a = random.nextInt();
b = random.nextInt(); // 模运算部分
start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
temp = a % b;
preventOptimization(temp);
}
long modulo = System.currentTimeMillis() - start; // 与运算部分
start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
temp = a & b;
preventOptimization(temp);
}
long and = System.currentTimeMillis() - start; // 计算两种运算的比
BigDecimal bigDecimal = new BigDecimal(and)
.divide(new BigDecimal(modulo), 6, ROUND_DOWN);
System.out.println(String.format("modulo: %sms, and: %sms, scale: %s", modulo, and, bigDecimal));
}
} // private static int preventOptimizationVar = 0; // A /**
* 用于阻止jvm的字节码优化技术生效,优化掉for循环中的代码<br>
*
* @param num
*/
private static void preventOptimization(int num) {
// preventOptimizationVar += num; // A
}

注意事项

启动时,需要添加JVM参数-Djava.compiler=NONE阻止虚拟机的JIT优化

一些迷之调用的解释

  1. 方法preventOptimization的作用本来是为了防止for循环内的运算单元被优化.从结果看,无法抵御JIT优化,实际上只阻止了字节码优化.
  2. 同样是方法preventOptimization.内部添加了一个对成员变量preventOptimizationVar的操作,本意同样是是为了阻止JIT优化,但效果出现偏差.
  3. 最终,只能使用JVM参数-Djava.compiler=NONE阻止JIT优化,同时调用空方法preventOptimization阻止字节码优化
  4. 为了整理其中的关联,进行如下整理

针对preventOptimization方法,preventOptimizationVar操作与-Djava.compiler=NONE参数之间的交叉测试

--------------------------- -Djava.compiler=NONE 不使用-Djava.compiler=NONE
preventOptimization(空方法) 目标结果 只能执行第一次while,之后除数为0抛出异常.应该是for循环被优化掉了
preventOptimization 执行变得极慢且比值随机位于1两侧.可能是因为操作成员变量的时间已经把运算的时间稀释了 两种运算的for的平均用时只有个位数的毫秒数.一般为4ms或5ms.可以断定发生了JIT优化.但是这又与完全跳过for循环的行为不同.中间产生了数毫秒的操作时间.
不调用preventOptimization 目标结果 只能执行第一次while,之后除数为0抛出异常.应该是for循环被优化掉了

注: 上面的测试结果基于intel平台上的ubuntu18.4操作系统.后面我会补上AMD平台上的Windows系统的执行表格.它们之间会有轻微的不同

后记

  1. 针对-Djava.compiler=NONE,明确的禁用了JIT优化
  2. 针对字节码优化需要回去翻书确认实际作用与效果
  3. 这个代码在不同的物理机上出现了一些差异.家中的电脑是AMD的锐龙CPU,其结果恒定为0.73左右.而在公司的Intel CPU上运行,结果稳定在0.87左右.
  4. 目前我无法这种计算方式是否是正确的,虽然得出了模运算运算慢的结论.身边没有大大,无法对我的这种做法进行评价.也就无法确定结果的正确性.也就是说,我有可能用了错误的方式,得到这正确的答案.这种可能的本末倒置实在让人头痛.

后记的后记

对于目前的这种情况.要想完全弄清谁快谁慢,其实可以用一个最简单也最直观的方法进行确认.那就是去翻JDK源码.先在字节码里找到负责运算与运算的指令,然后去找这个指令JDK实现

更新

看了下编译后的字节码,代码中使用了如下的指令进行操作

  1. 运算使用指令irem.将操作数栈的两个值进行余运算(注意,这里用的是余运算.它不同于模运算)
  2. 运算使用指令iand.将操作数栈的两个值进行与运算

下面需要找到JDK是怎么执行字节码文件中的每个指令的.

不要和我说什么几个阶段,每个阶段都干什么.这可能是个大坑.所以我得翻书(鸽了)啊

Java中"或"运算与"与"运算快慢的三三两两的更多相关文章

  1. Java中Byte类型数据在运算中的问题

    比如: byte a=1; byte b=2; byte c; c=a+b; //这样是计算不出c,是错误的 c=a+1; //这样也是不能计算c的 c=64+1; //为什么这样就能计算c,在Jav ...

  2. 关于JAVA中Byte数据类型二进制赋值运算报错问题

    自从JDK7更新之后,新增了二进制变量的表示,支持将整数类型用二进制来表示,用0b开头: 例如: byte b= (byte) 0b1000_0001; short s = (short) 0b100 ...

  3. java中&和&&的区别 位运算

    1.1. 逻辑与的运算符功能 1.1.1. 测试&& public static void main(String[] args) { int x=5; if (x==6 && ...

  4. Java中使用md5进行hash运算

    public class Md5Util { /** * @author Bean_bag * @description 进行Hash运算 * * @param input 参数字符串 * @retu ...

  5. 042、Java中逻辑运算之短路或运算“||”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  6. 041、Java中逻辑运算之普通或运算“|”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  7. 040、Java中逻辑运算之短路与运算“&&”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  8. 039、Java中逻辑运算之普通与运算“&”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  9. Java中「与运算,或运算,异或运算,取反运算。」

    版权声明一:本文为博主原创文章,转载请附上原文出处链接和本声明.版权声明二:本网站的所有作品会及时更新,欢迎大家阅读后发表评论,以利作品的完善.版权声明三:对不遵守本声明或其他违法.恶意使用本网内容者 ...

  10. java使用DateUtils对日期进行运算

    最近在写数据上传的程序,需要对Date进行一些数学运算,个人感觉在java中,日期的数学运算还是比较常用的,所以把Date的数学运算都玩了一下.试了一下,发现DateUtils这个工具类对于Date的 ...

随机推荐

  1. 如何使用pandas分析金融数据

    [摘要]pandas是数据分析师分析数据最常用的三方库之一,结合matplotlib,非常强大. 首先我们收集一些数据. 从东方财富客户端导出券商信托板块2018年11月1日的基础行情和财务数据.分别 ...

  2. luogu P1102 A-B 数对 |二分查找

    题目描述 出题是一件痛苦的事情! 题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈! 好吧,题目是这样的:给出一串数以及一个数字 C,要求计算出所有 A- ...

  3. Nginx(http协议代理 搭建虚拟主机 服务的反向代理 在反向代理中配置集群的负载均衡)

    Nginx 简介 Nginx (engine x) 是一个高性能的 HTTP 和反向代理服务.Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点(俄文:Рамблер)开 ...

  4. ZOJ-1709

    The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSu ...

  5. elasticsearch中mapping全解实战

    目录 Mapping简介 Mapping Type 分词器最佳实践 字段类型 text 类型 keyword 类型 date类型 object类型 nest类型 range类型 实战:同时使用keyw ...

  6. 嵌入式—ASCII码

    为了可以在计算机保存他们的文字,他们决定采用 127号之后的空位来表示这些新的字母.符号,还加入了很多画表格时需要用下到的横线.竖线.交叉等形状,一直把序号编到了最后一个状态255.从128 到255 ...

  7. docker-compose部署

    一.部署compose docker compose可以方便我们快捷高效地管理容器的启动.停止.重启等操作,它类似于linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比 ...

  8. JS内置对象-Array之splice-删插替

    splice-删除 var arr = [1, 2, 3, 4, 5, 6]; //删除 var delArr = arr.splice(1, 2) console.log(arr); // => ...

  9. JS基础-作用域

    作用域相关问题 下面的代码打印什么内容,为什么? // 情况 1 // 情况 2 var b = 10; var c = function b() { b = 20; console.log(b) } ...

  10. .Net,Java,Redis,Vue等技术视屏教程分享(不定期更新)

    前言 作为一个资深的收藏家决定把我收集的那些精品资源不定时更新分享给大家 .所有资源全是收集余网络或为大佬分享,内容仅供观摩学习交流之用.如果犯了您的权益,请联系我. 2019.12.19更新 ASP ...