从字节数组中的偏移量读取 32 位整数的最快方法
Fastest way to read a 32-bit integer from an offset in a byte array
之前在Java中关于从字节数组读取整数的讨论集中在你拥有的是四个字节的场景。我的情况略有不同:
20亿字节的固定数组。
输入:该数组的随机偏移量。 (尽管希望充分非随机以具有相当高的缓存命中率。)
这个操作会经常发生,所以需要尽快运行。如果 CPU 支持这样的话,理想的情况是存在 JIT 编译器可以识别并编译成未对齐加载指令的习惯用法。 (每个主流 CPU 都为每次内存访问中的未对齐支持付费,即使在不使用它的典型情况下也是如此。不妨利用它,这一次它会很有用。)
执行此操作最快的方法是什么?显然我可以手写 read-shift 循环,但是有更快的习惯用法吗?或者,如果要手动完成,哪种变体生成的代码最快?
如果重要的话,我正在使用 OpenJDK 17。
如果您不能或不希望使用内部 类,您可以使用 VarHandle
来访问它:
private static final VarHandle READ_ARRAY = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.nativeOrder());
public static void main(String[] args) {
byte[] arr = ...;
int pos = ...; // pos is the index into the byte array, and may be unaligned.
int result = (int) READ_ARRAY.get(arr, pos);
System.out.println(result);
}
虽然这增加了一些间接性,但最终它会在支持时调用 Unsafe.unalignedAccess()
。
如果您使用最佳实践(VarHandle
在 static final
字段中......),JIT 通常可以将所有内容内联到 Unsafe.unalignedAccess()
.
之前在Java中关于从字节数组读取整数的讨论集中在你拥有的是四个字节的场景。我的情况略有不同:
20亿字节的固定数组。
输入:该数组的随机偏移量。 (尽管希望充分非随机以具有相当高的缓存命中率。)
这个操作会经常发生,所以需要尽快运行。如果 CPU 支持这样的话,理想的情况是存在 JIT 编译器可以识别并编译成未对齐加载指令的习惯用法。 (每个主流 CPU 都为每次内存访问中的未对齐支持付费,即使在不使用它的典型情况下也是如此。不妨利用它,这一次它会很有用。)
执行此操作最快的方法是什么?显然我可以手写 read-shift 循环,但是有更快的习惯用法吗?或者,如果要手动完成,哪种变体生成的代码最快?
如果重要的话,我正在使用 OpenJDK 17。
如果您不能或不希望使用内部 类,您可以使用 VarHandle
来访问它:
private static final VarHandle READ_ARRAY = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.nativeOrder());
public static void main(String[] args) {
byte[] arr = ...;
int pos = ...; // pos is the index into the byte array, and may be unaligned.
int result = (int) READ_ARRAY.get(arr, pos);
System.out.println(result);
}
虽然这增加了一些间接性,但最终它会在支持时调用 Unsafe.unalignedAccess()
。
如果您使用最佳实践(VarHandle
在 static final
字段中......),JIT 通常可以将所有内容内联到 Unsafe.unalignedAccess()
.