【问题标题】:Java Converting long to bytes - which approach is more efficientJava将long转换为字节-哪种方法更有效
【发布时间】:2013-09-08 19:30:15
【问题描述】:

我有两种方法可以将 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 byte bit-shift endianness


【解决方案1】:

我建议你看看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 倍以上。

【讨论】:

    【解决方案2】:

    实际上有一个非常方便的解决方案可以将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));
    

    但是,与其他解决方案相比,我不知道它的性能。

    【讨论】:

    • 不幸的是,我正在尝试寻找一种替代方法。由于性能问题,不应该使用 ByteBuffer。
    • @user1071840 我明白了,但是您可能必须对候选人进行基准测试,这可能就是其中之一。此外,如果您对它们进行基准测试,可能值得检查原生字节缓冲区的性能。
    【解决方案3】:

    我更喜欢您的第二个解决方案,因为它的工作原理很清楚,并且很清楚它的工作原理。 第一个很容易被 1 出局。它需要相当多的思考来检查位移。考虑一下,在现代计算机上 shift 和 add 都是单周期操作。

    假设您正在从右到左剥离字节。 Java 传统上使用大端序。您希望他们先获得另一个 msb。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 2012-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多