Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';这是在字节数组上进行右位旋转/循环移位的最快方法_Java_Performance_Optimization_Bit Manipulation - Fatal编程技术网

Java 什么';这是在字节数组上进行右位旋转/循环移位的最快方法

Java 什么';这是在字节数组上进行右位旋转/循环移位的最快方法,java,performance,optimization,bit-manipulation,Java,Performance,Optimization,Bit Manipulation,如果我有数组: {01101111,11110000,00001111} // {111, 240, 15} 1位移位的结果是: {10110111,11111000,00000111} // {183, 248, 7} 数组大小不是固定的,移位将从1到7(包括1到7)。目前我有以下代码(工作正常): private static void shiftBitsRight(字节[]字节,最终整数右移){ 断言RightShift>=1&&RightShift>RightShift)|((字节[

如果我有数组:

{01101111,11110000,00001111} // {111, 240, 15}
1位移位的结果是:

{10110111,11111000,00000111} // {183, 248, 7}
数组大小不是固定的,移位将从1到7(包括1到7)。目前我有以下代码(工作正常):

private static void shiftBitsRight(字节[]字节,最终整数右移){

断言RightShift>=1&&RightShift>RightShift)|((字节[bytes.length-1]&0xff)>RightShift)|((上一个字节&0xff)找到答案的唯一方法是进行彻底的基准测试,最快的实现方式因平台而异。如果您真的需要优化,请使用类似这样的工具。

如果您愿意,您可以将其推广到long和多个位移位

// 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;
//对于1位右移:
//首先将每个字节右转一次
对于(i=0;i=1;){
b[i]&=0x7f;
b[i]|=(b[i-1]&0x80);
}
//把最右边的位子放在左边
b[0]=(b[0]&0x7f)|位;

假设定义了
rotr

您可以做的一件事是将
(字节[a]&0xff)>>b
替换为
字节[a]>>b

此外,左移时不需要
&0xff

尽管这可能无关紧要,但将final添加到
tmp
或将声明移出循环可能会有所帮助

另一件可以尝试的事情是:

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);
 }
inttmp=bytes[bytes.length-1];
对于(int i=bytes.length-2;i>=0;i--){
tmp=(tmp>右移);
}
然后再解字节[bytes.length-1]

如果你迷信的话,反循环也会有帮助。我以前见过它的工作原理

每次循环分析:

你的:3个作业,两班制,一个或多个演员


我的:两个作业,两个班次,一次或一次转换。

用于获得一个缓冲区,用于包装您的
字节[]
,然后使用以获得一个视图,该视图允许您按照@NiklasB的建议提取和操作
long
s。从而利用硬件的能力来移动大块的位。

我认为首先将
long
分组将有助于提高性能。如果这是用于图形,另一个需要考虑的选项是使用一个游程长度编码格式。然后换挡不必改变行中所有的运行长度。<代码>长< /Cord>可以提高性能,但它会因机器而异。(有时 INT/COME >会更好)。使用长[]可以比使用字节[4]快4X到8X。对于相同数量的数据。不幸的是,将它们分组为long或int在我的情况下不会有好处,因为我需要在移位后获取此数组的摘要,而MessageDigest对象需要一个字节数组,因此每次完成位移位时,我都需要将long展开为字节。请解释?(如果OP的问题有比这更具体的单一通用答案,我会非常惊讶。)
(byte[a]&0xff)>>b
byte[a]>>>b
是不等价的!在前者中,在删除高位字节后,左侧提升为int
,产生所需的结果。在后者中,提升发生,然后发生无符号移位,因此
a
左侧的位将是
a
的符号位,然后是
b
0的数字。
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);
 }