我听说英特尔使用小端架构,因此以小端方式为 CPU 提供字节缓冲区更好/更快。我还听说网络可以使用大端。
那么有人可以解释在使用 Java NIO ByteBuffers 进行网络 IO 时应该使用什么,换句话说,当通过线路从一台机器发送字节到另一台机器时应该使用什么?
一直使用小端序?有关系吗?
我听说英特尔使用小端架构,因此以小端方式为 CPU 提供字节缓冲区更好/更快。我还听说网络可以使用大端。
那么有人可以解释在使用 Java NIO ByteBuffers 进行网络 IO 时应该使用什么,换句话说,当通过线路从一台机器发送字节到另一台机器时应该使用什么?
一直使用小端序?有关系吗?
那么有人可以解释一下在使用 Java NIO ByteBuffers 进行网络 IO 时应该使用什么,
它必须与另一端的期望相匹配。
当通过线路从一台机器发送字节到另一台机器时?
如果没关系,我会保留默认值,因为您获得的性能提升不太重要,即使对于 1 Gb 网络也是如此。
如果你想使用机器的本机字节序,你可以使用
ByteBuffer.order(ByteBuffer.nativeOrder());
这是需要多长时间的比较
public static void main(String... args) {
ByteBuffer bb = ByteBuffer.allocateDirect( 1024 * 1024);
for (int i = 0; i < 5; i++) {
testEndian(bb.order(ByteOrder.LITTLE_ENDIAN));
testEndian(bb.order(ByteOrder.BIG_ENDIAN));
}
}
public static void testEndian(ByteBuffer bb) {
long start = System.nanoTime();
int runs = 100;
for (int i = 0; i < runs; i++) {
bb.clear();
int count = 0;
while (bb.remaining() > 3)
bb.putInt(count++);
bb.flip();
int count2 = 0;
while (bb.remaining() > 3)
if (count2++ != bb.getInt())
throw new AssertionError();
}
long time = System.nanoTime() - start;
System.out.printf(bb.order() + " took %,d μs to write/read %,d ints%n", time / 1000 / runs, bb.capacity() / 4);
}
印刷
LITTLE_ENDIAN took 1,357 μs to write/read 262,144 ints
BIG_ENDIAN took 1,484 μs to write/read 262,144 ints
LITTLE_ENDIAN took 867 μs to write/read 262,144 ints
BIG_ENDIAN took 880 μs to write/read 262,144 ints
LITTLE_ENDIAN took 860 μs to write/read 262,144 ints
BIG_ENDIAN took 881 μs to write/read 262,144 ints
LITTLE_ENDIAN took 853 μs to write/read 262,144 ints
BIG_ENDIAN took 879 μs to write/read 262,144 ints
LITTLE_ENDIAN took 858 μs to write/read 262,144 ints
BIG_ENDIAN took 871 μs to write/read 262,144 ints
在 1 MB 的数据中,使用 little endian 节省了大约 20 μs(1 ms 的 1/1000)。在 1 Gb 上发送 1 MB 大约需要 9,000 μs。
基本上从来没有。大多数网络协议都以“网络字节顺序”定义,即大端。如果您知道另一端有 Intel 架构,您可以使用 little-endian,但您真的知道吗?永远?