我正在编写需要高度优化速度的底层代码,每个CPU周期都很重要。由于代码是用Java编写的,相比如C语言,我无法编写如此底层的代码,但我想尽可能地发挥VM的所有功能。
我正在处理一个字节数组。目前我主要关注代码中的两个部分。第一个部分是:
int key = (data[i] & 0xff)
| ((data[i + 1] & 0xff) << 8)
| ((data[i + 2] & 0xff) << 16)
| ((data[i + 3] & 0xff) << 24);
第二个是:
key = (key << 15) | (key >>> 17);
从性能表现来看,我猜测这些语句没有按照我预期的方式进行优化。第二个语句基本上是一个ROTL 15, key
。第一个语句将4个字节加载到一个int中。这里的0xff掩码只是为了补偿访问的字节如果是负数时造成的隐式强制类型转换到int后添加的符号位。这应该很容易转换为高效的机器代码,但令我惊讶的是如果我去掉掩码,性能反而提高了。 (当然这会破坏我的代码,但是我很想知道会发生什么。)
这里发生了什么?最常见的Java虚拟机是否会在JIT期间优化此代码,就像一个好的C++编译器会优化等价的C++代码一样?我能影响这个过程吗?设置-XX:+AggressiveOpts
似乎没有任何区别。
(CPU:x64,平台:Linux / HotSpot)