Является ли установка порядка ByteBuffer (в зависимости от использования буфера) безопасной / хорошей оптимизацией? - PullRequest
4 голосов
/ 14 февраля 2012

Java - Big-Endian; Сетевой стек является Big-Endian; Intel / AMD (в основном все наши компьютеры) и процессоры ARM (наиболее распространенные чипы Android и iOS ) также имеют младший порядок байтов.

Учитывая все это, если я выделяю прямой ByteBuffer для различных применений, будет ли хорошей идеей всегда пытаться сопоставить порядковый номер нативного взаимодействия?

Более конкретно:

  • Сетевой буфер: оставьте его Big-Endian.
  • Буфер файлов (на x86): Little-Endian.
  • OpenGL / собственный буфер процесса: Little-Endian.

и так далее ...

Я спрашиваю об этом, потому что я никогда не думал о Endian-ness моих ByteBuffers, но, посмотрев некоторые другие вопросы о SO и о влиянии на производительность , это может иметь Кажется, это того стоит или, по крайней мере, кое-что, о чем я должен больше знать, используя ByteBuffers.

Или, может быть, здесь есть и обратная сторона беспокойства о порядке байтов, который я пропускаю и хотел бы знать?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

В цитируемой вами статье указывается, что разница довольно мала.(Возможно, нет)

Приведенные результаты не показывают последовательного улучшения, и использование новейших JVM может сократить разрыв.


  • Когда я включаю "собственное упорядочение байтов"(что на самом деле небезопасно, если машина использует другое соглашение о порядке байтов):
mmap: 1.358
bytebuffer: 0.922
regular i/o: 1.387
  • Когда я закомментирую оператор порядка и использую большой по умолчанию-диандиальный порядок:
mmap: 1.336
bytebuffer: 1.62
regular i/o: 1.467

Существует измеренная разница, но она мала в общей схеме вещей.Если вы хотите, чтобы это было намного быстрее, единственный вариант, который я нашел, который имеет большое значение, - это использовать Unsafe напрямую, и в этом случае доступен только собственный порядок.

Даже тогда это помогает только в наиболее чувствительных к задержкам приложениях.

Небезопасное еще более интересно с кодом и комментариями.;)

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/misc/Unsafe.java

2 голосов
/ 14 февраля 2012

Если вы используете свой ByteBuffer для чтения и сохранения байтов, порядок байтов не имеет значения, просто используйте значение по умолчанию.

Если вы читаете и пишете небайтовые типы примитивов (short, int, float, long, double), то базовый процессор должен будет выполнить дополнительную работу, если Endianness ЦП (ByteOrder.nativeOrder ()) отличается от по умолчанию Java Big Endianness. Если вы прочтете другие вопросы SO, с которыми вы связались, вы сможете понять, почему ... Процессору придется перебрасывать байты, чтобы выполнить любую работу со связанными примитивными типами. Эта операция перестановки (замены) байтов израсходует некоторые циклы ЦП.

Быстрый пример с использованием двух значений Short 1 и 2. Предполагается, что ваш процессор является процессором x86.

short A = 1;
short B = 2;
short C = A + B;

Если ваш собственный процессор ожидает порядка байтов

MOV ax, short[A] ; ax register [ 01, 00 ]
MOV bx, short[B] ; bx register [ 02, 00 ]
ADD ax, bx ; ax register [ 03, 00 ]
MOV short[C], ax ; C [ 03, 00 ]

И вы даете этому порядковый номер, он должен выполнять дополнительную работу.

MOV ax, short[A] ; ax register [ 00, 01 ]
MOV bx, short[B] ; bx register [ 00, 02 ]
BSWAP ax ; ax register [ 01, 00 ]
BSWAP bx ; bx register [ 02, 00 ]
ADD ax, bx ; ax register [ 03, 00 ]
MOV short[C], ax ; C [ 03, 00 ]

Итак, на самом низком уровне это имеет значение, но если вы не заметили / не профилировали серьезное узкое место в вашем коде, просто используйте значение по умолчанию.

...