[英]What's the fastest way to do a right bit rotation/circular shift on a byte array
If I have the array: 如果我有阵列:
{01101111,11110000,00001111} // {111, 240, 15}
The result for a 1 bit shift is: 1位移位的结果是:
{10110111,11111000,00000111} // {183, 248, 7}
The array size is not fixed, and the shifting will be from 1 to 7 inclusive. 阵列大小不固定,移位将从1到7(包括1和7)。 Currently I have the following code (which works fine):
目前我有以下代码(工作正常):
private static void shiftBitsRight(byte[] bytes, final int rightShifts) {
assert rightShifts >= 1 && rightShifts <= 7;
final int leftShifts = 8 - rightShifts;
byte previousByte = bytes[0]; // keep the byte before modification
bytes[0] = (byte) (((bytes[0] & 0xff) >> rightShifts) | ((bytes[bytes.length - 1] & 0xff) << leftShifts));
for (int i = 1; i < bytes.length; i++) {
byte tmp = bytes[i];
bytes[i] = (byte) (((bytes[i] & 0xff) >> rightShifts) | ((previousByte & 0xff) << leftShifts));
previousByte = tmp;
}
}
Is there a faster way to achieve this than my current approach? 有没有比我目前的方法更快的方法来实现这一目标?
One of the things you can do is replace (byte[a]&0xff)>>b
with byte[a]>>>b
您可以做的一件事是用
byte[a]>>>b
替换(byte[a]&0xff)>>b
byte[a]>>>b
Also, you don't need &0xff
when you are left shifting. 此外,当您离开时,您不需要
&0xff
。
Although it may not matter, either adding final to tmp
or moving the declaration out of the loop may help a tiny bit. 虽然可能无关紧要,但是将最终添加到
tmp
或将声明移出循环可能会有所帮助。
Another thing might try is: 另一件事可能是尝试:
int tmp=bytes[bytes.length-1];
for (int i = bytes.length-2; i >=0; i--) {
tmp=(tmp<<8)|bytes[i];
bytes[i] = (byte) (tmp>>>rightShifts);
}
Then you solve bytes[bytes.length-1] afterwards. 然后你解决字节[bytes.length-1]。
That reverse for loop may also help if you are superstitious. 如果你迷信,反向循环也可能有所帮助。 I've seen it work before.
我以前见过它。
Loop Analysis per pass: 每次循环分析:
yours: 3 assignments, two shifts, one or, one cast. 你的:3个作业,两个班次,一个或一个演员。
mine: 2 assignments, two shifts, one or, one cast. 我的:2个任务,两个轮班,一个或一个演员。
Use ByteBuffer.wrap
to get a buffer that wraps your byte[]
and then use ByteBuffer.asLongBuffer()
to get a view that allows you to extract and manipulate long
s as suggested by @NiklasB. 使用
ByteBuffer.wrap
获取一个包装你的byte[]
的缓冲区,然后使用ByteBuffer.asLongBuffer()
获取一个视图,允许你按照@NiklasB的建议提取和操作long
。 thus taking advantage of the hardware's ability to shift larger chunks of bits. 从而利用硬件移动较大块位的能力。
You can generalize this to longs and more than one bit shift if you like 如果您愿意,可以将其概括为longs和多位移位
// for a 1-bit rightshift:
// first rotate each byte right by one
for (i = 0; i < n; i++) b[i] = rotr(b[i], 1);
// get rightmost bit
bit = b[n-1] & 0x80;
// copy high order bit from adjacent byte
for (i = n; --i >= 1;){
b[i] &= 0x7f;
b[i] |= (b[i-1] & 0x80);
}
// put in the rightmost bit on the left
b[0] = (b[0] & 0x7f) | bit;
assuming rotr
is defined. 假设定义了
rotr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.