由于29位整数在AMF中很受欢迎,因此我想结合已知的最快/最佳例程。我们的库中目前存在两个例程,可以在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;
}
答案 0 :(得分:2)
通常我会用位操作来做这件事。第二个版本最终可能会被JVM优化到接近这个版本的东西,但是人们无法确定。现在,这只是24位,跟随你的样本,但问题是“29位整数”。我不确定你真正想要的是什么。
public static int readMediumInt(ByteBuffer buf) {
return ((buf.get() & 0xFF) << 16)
| ((buf.get() & 0xFF) << 8)
| ((buf.get() & 0xFF);
}
答案 1 :(得分:2)
如果您确实想要读取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);
}
答案 2 :(得分:1)
最重要的变化是避免在方法中分配对象。顺便说一下,你的微基准没有重置“开始”,所以第二个结果包括第一个方法使用的时间。此外,您需要多次运行微基准测试,否则即时编译器无法运行。我建议使用类似于
的方法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);
}
}
}
我的结果: