我有两种方法可以将 long 转换为字节数组。
for (int i = 0; i < 7; i++) {
data[pos + i] = (byte) (value >> (7- i - 1 << 3));
}
和
for (int i = 7; i >= 0; --i) {
data[p + i] = (byte)(newl & 0xff);
newl >>= 8;
}
这两种操作中哪一种更有效?
我有两种方法可以将 long 转换为字节数组。
for (int i = 0; i < 7; i++) {
data[pos + i] = (byte) (value >> (7- i - 1 << 3));
}
和
for (int i = 7; i >= 0; --i) {
data[p + i] = (byte)(newl & 0xff);
newl >>= 8;
}
这两种操作中哪一种更有效?
我建议你看看 Java 代码是如何做到的。
public final void writeLong(long v) throws IOException {
writeBuffer[0] = (byte)(v >>> 56);
writeBuffer[1] = (byte)(v >>> 48);
writeBuffer[2] = (byte)(v >>> 40);
writeBuffer[3] = (byte)(v >>> 32);
writeBuffer[4] = (byte)(v >>> 24);
writeBuffer[5] = (byte)(v >>> 16);
writeBuffer[6] = (byte)(v >>> 8);
writeBuffer[7] = (byte)(v >>> 0);
out.write(writeBuffer, 0, 8);
incCount(8);
}
如您所见,没有循环,您的操作就更少了。
最快的方法是根本不这样做,而是使用 Unsafe.writeLong() 因为这需要很长时间并将其直接放入内存而不是将其分解为字节。这可以快 10 倍以上。
实际上有一个非常方便的解决方案将 a 转换long
为字节,使用 的实例ByteBuffer
:
long longValue = 123858585l;
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.putLong(longValue);
// without copy, accesses directly the interal array
System.out.println(Arrays.toString(buffer.array()));
// acquire a copy of the buffer's internal byte array
byte[] longInBytes = new byte[8];
buffer.rewind();
buffer.get(longInBytes);
System.out.println(Arrays.toString(longInBytes));
但是,与其他解决方案相比,我不知道它的性能。
我更喜欢你的第二个解决方案,因为它是如何工作的并且很清楚它是如何工作的。第一个很容易被 1 出局。它需要相当多的思考来检查位移。考虑到 shift 和 add 都是现代计算机上的单周期操作。
考虑到您正在从右到左剥离字节。Java 传统上使用大端序。您首先希望他们获得另一个 msb。