0

使用 Android Profiler 工具时,我发现我在代码的性能关键区域中使用了大量的 ByteBuffer。我一直致力于尽可能优化最大的性能损失(还没有被迫进行循环优化之类的工作),并且 ByteBuffer 代码看起来可以很容易地被另一个/更好的解决方案替换。

问题:从位于 ByteBuffer 流中的 4 个连续字节中获取一个 int,该字节可以是任意长度,当前使用临时 ByteBuffer 完成(见下文,特别是 //<<< 部分)并抓取所需的字节以形成一个 int。有没有更简单的流程?

private int peekStreamData(ByteBuffer stream, int count) {
    int data = 0;
    int stream_field = streamField;
    int stream_field_bit_index = streamFieldBitIndex;
    byte[] streamArr = stream.array();
    ByteBuffer bb = ByteBuffer.allocate(4);
    while (count > (32 - stream_field_bit_index) && streamIndex < (imageStream.capacity() >> 2)) {
        data = (data << (32 - stream_field_bit_index)) | ( stream_field >>> stream_field_bit_index);
        count -= 32 - stream_field_bit_index;

        bb.put(0,streamArr[streamIndex * 4 + 3]);  //<<<
        bb.put(1,streamArr[streamIndex * 4 + 2]);  //<<<
        bb.put(2,streamArr[streamIndex * 4 + 1]);  //<<<
        bb.put(3,streamArr[streamIndex * 4 + 0]);  //<<<
        stream_field = bb.getInt();                //<<<        
        stream_field_bit_index = 0;
    }
    if (count > 0)
        data = (data << count) | (stream_field >>> (32 - count));
    return data;//data;
}

请随时指出任何错误。直到最近我才使用过 ByteBuffers,并且很想学习。

4

3 回答 3

2

这些线

    bb.put(0,streamArr[streamIndex * 4 + 3]);  //<<<
    bb.put(1,streamArr[streamIndex * 4 + 2]);  //<<<
    bb.put(2,streamArr[streamIndex * 4 + 1]);  //<<<
    bb.put(3,streamArr[streamIndex * 4 + 0]);  //<<<
    stream_field = bb.getInt();                //<<<

可以用第二个 ByteBuffer 替换为以下内容。

    stream_field = stream.getInt(streamIndex * 4);

我怀疑其他许多代码都可以简化,但我不清楚它的作用或为什么甚至有一个循环来做它。

于 2011-07-08T22:50:53.643 回答
1

你有没有尝试过:

stream_field = (streamArr[streamIndex * 4 + 0] & 0xFF) | ((streamArr[streamIndex * 4 + 1] & 0xFF) << 8) | ((streamArr[streamIndex * 4 + 2] & 0xFF) << 16) | ((streamArr[streamIndex * 4 + 3] & 0xFF) << 24);

或者:

stream_field = ((streamArr[streamIndex * 4 + 0] & 0xFF) << 24) | ((streamArr[streamIndex * 4 + 1] & 0xFF) << 16) | ((streamArr[streamIndex * 4 + 2] & 0xFF) << 8) | (streamArr[streamIndex * 4 + 3] & 0xFF);

取决于字节序。

编辑:在 Javabyte中是签名的,所以他们需要屏蔽。已更正。

于 2011-07-08T22:23:31.607 回答
0

您可以将四个字节组合成一个 int 而不是使用临时ByteBuffer。默认情况下,四个字节采用大端字节序。此外,您不必连续计算四次“streamIndex * 4”。

于 2011-07-08T22:15:40.457 回答