Вот результат, который я не могу обернуть вокруг, несмотря на обширное чтение источника JDK и рассмотрение внутренних процедур.ByteBuffer.putLong ~ 2x быстрее с не-родным ByteOrder
Я тестирую очистку ByteBuffer
, выделенную allocateDirect
с использованием ByteBuffer.putLong(int index, long value)
. Основываясь на коде JDK, это приводит к одной записи в 8 байт, если буфер находится в «собственном байтовом порядке» или байтовой свопе, за которым следует то же самое, если это не так.
Так что я бы ожидал, что основной порядок байтов (маленький конец для меня) будет по крайней мере так же быстро, как и неродной. однако, как выясняется, неродные быстрее на 2x.
Вот мой тест в Суппорт 0.5x:
...
public class ByteBufferBench extends SimpleBenchmark {
private static final int SIZE = 2048;
enum Endian {
DEFAULT,
SMALL,
BIG
}
@Param Endian endian;
private ByteBuffer bufferMember;
@Override
protected void setUp() throws Exception {
super.setUp();
bufferMember = ByteBuffer.allocateDirect(SIZE);
bufferMember.order(endian == Endian.DEFAULT ? bufferMember.order() :
(endian == Endian.SMALL ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN));
}
public int timeClearLong(int reps) {
ByteBuffer buffer = bufferMember;
while (reps-- > 0) {
for (int i=0; i < SIZE/LONG_BYTES; i+= LONG_BYTES) {
buffer.putLong(i, reps);
}
}
return 0;
}
public static void main(String[] args) {
Runner.main(ByteBufferBench.class,args);
}
}
Результаты:
benchmark type endian ns linear runtime
ClearLong DIRECT DEFAULT 64.8 =
ClearLong DIRECT SMALL 118.6 ==
ClearLong DIRECT BIG 64.8 =
Это согласуется. Если я поменю putLong
на putFloat
, это примерно в 4 раза быстрее для собственного заказа. Если вы посмотрите на то, как putLong
работает, он делает абсолютно больше работы в неродной случае:
private ByteBuffer putLong(long a, long x) {
if (unaligned) {
long y = (x);
unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
} else {
Bits.putLong(a, x, bigEndian);
}
return this;
}
Обратите внимание, что unaligned
верно в любом случае. Единственное различие между нативным и неместным порядком байтов - Bits.swap
, что благоприятствует собственному случаю (little-endian).
Какая у вас система? – Kayaman
Вы используете только часть (около 1/8) буфера, поскольку 'putLong' ожидает смещение в байтах. Я не понимаю, почему доступ должен быть неравнозначным (когда вы исправляете байтовое и длинное смещение). Мои [результаты] (https://microbenchmarks.appspot.com/runs/0bd9f0ea-96d4-4cfd-97ce-105a3ccc9a1d) (созданные с помощью суппорта 1.0 beta) отличаются. – maaartinus
@ Kayaman - Я нахожусь на Xeon W3580, но я не ожидаю, что он будет отличаться по архитектуре x86. – BeeOnRope