簡體   English   中英

在字節數組上執行右位旋轉/循環移位的最快方法是什么

[英]What's the fastest way to do a right bit rotation/circular shift on a byte array

如果我有陣列:

{01101111,11110000,00001111} // {111, 240, 15}

1位移位的結果是:

{10110111,11111000,00000111} // {183, 248, 7}

陣列大小不固定,移位將從1到7(包括1和7)。 目前我有以下代碼(工作正常):

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;
   }
}

有沒有比我目前的方法更快的方法來實現這一目標?

找到答案的唯一方法是徹底的基准測試,最快的實現方式因平台而異。 如果您真的需要優化,請使用像Caliper這樣的工具。

您可以做的一件事是用byte[a]>>>b替換(byte[a]&0xff)>>b byte[a]>>>b

此外,當您離開時,您不需要&0xff

雖然可能無關緊要,但是將最終添加到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);
 }

然后你解決字節[bytes.length-1]。

如果你迷信,反向循環也可能有所幫助。 我以前見過它。

每次循環分析:

你的:3個作業,兩個班次,一個或一個演員。

我的:2個任務,兩個輪班,一個或一個演員。

使用ByteBuffer.wrap獲取一個包裝你的byte[]的緩沖區,然后使用ByteBuffer.asLongBuffer()獲取一個視圖,允許你按照@NiklasB的建議提取和操作long 從而利用硬件移動較大塊位的能力。

如果您願意,可以將其概括為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;

假設定義了rotr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM