起因是碰巧需要写段小程序,需要检测int x+int y、int x-int y、int x*int y是否会出现overflow或underflow。其实原理蛮简单的,但是需要兼顾一些效率。我调研了一些材料,发现有几种代码的写法:
① int r = x + y; 然后利用位运算符判断:if (((x ^ r) & (y ^ r)) < 0) ……
② long r = (long) x + y; 然后判断:r == (int) r ……
③ 跟①思路一致,但是位运算的写法是: if (((x & y & ~r) | (~x & ~y & r)) < 0) ……
采用①方式的比如Java8的Math. addExact()
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Math.java#l779
采用②方式的比如Google Guava的IntMath . checkedAdd () https://github.com/google/guava/blob/master/guava/src/com/google/common/math/IntMath.java
采用③方式的是StackOverflow的一个回答 http://stackoverflow.com/questions/3001836/how-does-java-handle-integer-underflows-and-overflows-and-how-would-you-check-fo
那么问题来了:
[Q1] 如何定性分析这三种写法的效率?简单的想,可以分析生成的bytecode分别有几条指令,每条逻辑执行时间是多少,但是考虑到实际执行时JIT出来的指令及序列会不一样,导致简单分析的结果不对;
[Q2] 如何定量测试这三种写法的效率?就算我们写了测试的code来循环很多次,得到每次平均运行时间,但是实际使用的环境中,如果把这段检测overflow/underflow的代码放到方法里被调用,是不是方法调用开销的本身就比这三段写法的性能差异大多了?再比如在笔记本本地的Windows环境下测试,三者的效率有个相对高低,是否会与服务器Linux环境下实际跑时的相对高低一致呢?
可能问题有些simple & naive, 但还是想看到各位的解答和探讨,谢谢各位~