![](/img/trans.png)
[英]Fastest most efficient way to determine decimal value is integer in Java
[英]Fastest and most efficient conversion of a byte array to a 29 bit integer in Java
由於AMF中普遍使用29位整數,因此我想結合已知的最快/最佳例程。 我們的庫中當前存在兩個例程,可以在ideone上對其進行實時測試http://ideone.com/KNmYT
這是快速參考的來源
public static int readMediumInt(ByteBuffer in) {
ByteBuffer buf = ByteBuffer.allocate(4);
buf.put((byte) 0x00);
buf.put(in.get());
buf.put(in.get());
buf.put(in.get());
buf.flip();
return buf.getInt();
}
public static int readMediumInt2(ByteBuffer in) { byte[] bytes = new byte[3]; in.get(bytes); int val = 0; val += bytes[0] * 256 * 256; val += bytes[1] * 256; val += bytes[2]; if (val < 0) { val += 256; } return val; }
通常我會用位操作來做到這一點。 第二個版本最終可能會被JVM優化為接近此版本的版本,但是不能確定。 現在,跟隨您的樣本,它只有24位,但問題是“ 29位整數”。 我不確定您真正想要哪個。
public static int readMediumInt(ByteBuffer buf) {
return ((buf.get() & 0xFF) << 16)
| ((buf.get() & 0xFF) << 8)
| ((buf.get() & 0xFF);
}
如果您確實想讀取AMF 29位整數,則應該可以完成此工作(假設我正確理解了格式):
private static int readMediumInt(ByteBuffer buf) {
int b0, b1, b2;
if ((b0 = buf.get()) >= 0) return b0;
if ((b1 = buf.get()) >= 0) return ((b0 << 7) & ((~(-1 << 7)) << 7)) | b1;
if ((b2 = buf.get()) >= 0) return ((b0 << 14) & ((~(-1 << 7)) << 14)) | ((b1 << 7) & ((~(-1 << 7)) << 7)) | b2;
return ((b0 << 22) & ((~(-1 << 7)) << 22)) | ((b1 << 15) & ((~(-1 << 7)) << 15)) | ((b2 << 8) & ((~(-1 << 7)) << 8)) | (buf.get() & 0xff);
}
最重要的更改是避免在方法內分配對象。 順便說一下,您的微基准測試沒有重置“開始”,因此第二個結果包括第一種方法所用的時間。 另外,您需要多次運行微基准測試,否則即時編譯器將無法運行。 我建議使用類似的方法
public static int readMediumInt3(ByteBuffer buf) {
return ((buf.get() & 0xff) << 16) +
((buf.get() & 0xff) << 8) +
((buf.get() & 0xff));
}
完整的代碼是:
import java.nio.ByteBuffer;
public class Main {
public static int readMediumInt(ByteBuffer in) {
ByteBuffer buf = ByteBuffer.allocate(4);
buf.put((byte) 0x00);
buf.put(in.get());
buf.put(in.get());
buf.put(in.get());
buf.flip();
return buf.getInt();
}
public static int readMediumInt2(ByteBuffer in) {
byte[] bytes = new byte[3];
in.get(bytes);
int val = 0;
val += bytes[0] * 256 * 256;
val += bytes[1] * 256;
val += bytes[2];
if (val < 0) {
val += 256;
}
return val;
}
public static int readMediumInt3(ByteBuffer buf) {
return ((buf.get() & 0xff) << 16) +
((buf.get() & 0xff) << 8) +
((buf.get() & 0xff));
}
public static void main(String[] args) {
Main m = new Main();
for (int i = 0; i < 5; i++) {
// version 1
ByteBuffer buf = ByteBuffer.allocate(4);
buf.putInt(424242);
buf.flip();
long start;
start = System.nanoTime();
for (int j = 0; j < 10000000; j++) {
buf.position(0);
readMediumInt(buf);
}
start = System.nanoTime() - start;
System.out.printf("Ver 1: elapsed: %d ms\n", start / 1000000);
// version 2
ByteBuffer buf2 = ByteBuffer.allocate(4);
buf2.putInt(424242);
buf2.flip();
start = System.nanoTime();
for (int j = 0; j < 10000000; j++) {
buf2.position(0);
readMediumInt2(buf2);
}
start = System.nanoTime() - start;
System.out.printf("Ver 2: elapsed: %d ms\n", start / 1000000);
// version 3
ByteBuffer buf3 = ByteBuffer.allocate(4);
buf3.putInt(424242);
buf3.flip();
start = System.nanoTime();
for (int j = 0; j < 10000000; j++) {
buf3.position(0);
readMediumInt3(buf3);
}
start = System.nanoTime() - start;
System.out.printf("Ver 3: elapsed: %d ms\n", start / 1000000);
}
}
}
我的結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.