bytebufferab java_java-使用非本地ByteOrder时ByteBuffer.putLong快2倍

尽管广泛阅读了JDK源代码并检查了内在例程,但我还是不能一概而论.

我正在测试清除使用ByteBuffer.putLong(int index,long value)用allocateDirect分配的ByteBuffer.基于JDK代码,如果缓冲区为“本机字节顺序”,则将导致单个8字节的写操作;如果不按字节交换,则将导致相同的写操作.

因此,我希望本机字节顺序(对我来说是小尾数)至少与非本机字节一样快.事实证明,非本地人的速度快约2倍.

这是我在Caliper 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,它偏爱本机大小写(小尾数).

解决方法:

总结机械同情邮件列表中的讨论:

1. OP所描述的异常无法在我的设置(JDK7u40 / Ubuntu13.04 / i7)上重现,从而导致所有情况下堆和直接缓冲区的性能均保持一致,直接缓冲区具有巨大的性能优势:

BYTE_ARRAY DEFAULT 211.1 ==============================

BYTE_ARRAY SMALL 199.8 ============================

BYTE_ARRAY BIG 210.5 =============================

DIRECT DEFAULT 33.8 ====

DIRECT SMALL 33.5 ====

DIRECT BIG 33.7 ====

Bits.swap(y)方法被固有地限制在一条指令中,因此不能/不应该真正考虑很大的差异/开销.

2,以上结果(即与OP经验相矛盾)由幼稚的手推基准和另一位参与者编写的JMH基准独立确认.

这使我相信您正在遇到一些本地问题或某种基准框架问题.如果其他人可以进行实验并查看他们是否可以重现您的结果,那将很有价值.

标签:microbenchmark,disruptor-pattern,nio,caliper,java

来源: https://codeday.me/bug/20191030/1967049.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值