这是通过实验的方式得到的结论.因为没有大大可以进行明确指导,所以我以最终运行的结果为准.欢迎指正.
@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优化
preventoptimization
的作用本来是为了防止for循环内的运算单元被优化.从结果看,无法抵御jit优化,实际上只阻止了字节码优化.preventoptimization
.内部添加了一个对成员变量preventoptimizationvar
的操作,本意同样是是为了阻止jit优化,但效果出现偏差.-djava.compiler=none
阻止jit优化,同时调用空方法preventoptimization
阻止字节码优化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系统的执行表格.它们之间会有轻微的不同
-djava.compiler=none
,明确的禁用了jit优化对于目前的这种情况.要想完全弄清谁快谁慢,其实可以用一个最简单也最直观的方法进行确认.那就是去翻jdk源码.先在字节码里找到负责与运算与模运算的指令,然后去找这个指令的jdk实现
irem
.将操作数栈的两个值进行余运算(注意,这里用的是余运算.它不同于模运算)iand
.将操作数栈的两个值进行与运算不要和我说什么几个阶段,每个阶段都干什么.这可能是个大坑.所以我得翻书(鸽了)啊
如对本文有疑问, 点击进行留言回复!!
Java/Python实现 LeetCode剑指Offer 14-I.剪绳子(动态规划)
Python - paramiko 模块远程执行ssh 命令 nohup 不生效的问题解决
网友评论