Замена для Java ByteBuffer в этом случае? - PullRequest
0 голосов
/ 09 июля 2011

Работая с инструментом Android Profiler, я обнаружил, что я использую множество ByteBuffers в критической области моего кода. Я работал над максимально возможной оптимизацией самых больших падений производительности (пока не был вынужден заниматься такими вещами, как оптимизация цикла), и код ByteBuffer выглядит так, как будто его можно легко заменить другим / лучшим решением.

Проблема : Получение целого числа из 4 последовательных байтов, расположенных в потоке ByteBuffer, которые могут иметь любую длину, в настоящее время выполняется (см. Ниже, в частности, // <<< parts) с временным ByteBuffer и захватывает необходимые байты, чтобы сформировать int. Есть ли более простой процесс? </p>

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 и хотел бы научиться.

Ответы [ 3 ]

2 голосов
/ 09 июля 2011

Эти строки

    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 = stream.getInt(streamIndex * 4);

Я подозреваю, что большая часть другого кода может быть упрощена, но мне не ясно, что он делает или почему для этого даже есть цикл.

1 голос
/ 09 июля 2011

Вы пробовали:

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);

в зависимости от endiannes.

РЕДАКТИРОВАТЬ: В Java byte подписано, поэтому они должны маскироваться. Исправлено.

0 голосов
/ 09 июля 2011

Вы можете просто объединить четыре байта в целое число вместо использования временного ByteBuffer . По умолчанию четыре байта расположены в порядке байтов с прямым порядком байтов. Кроме того, вам не нужно вычислять «streamIndex * 4» четыре раза подряд.

...