2

我听说英特尔使用小端架构,因此以小端方式为 CPU 提供字节缓冲区更好/更快。我还听说网络可以使用大端。

那么有人可以解释在使用 Java NIO ByteBuffers 进行网络 IO 时应该使用什么,换句话说,当通过线路从一台机器发送字节到另一台机器时应该使用什么?

一直使用小端序?有关系吗?

4

2 回答 2

3

那么有人可以解释一下在使用 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。

于 2012-10-01T18:21:36.877 回答
0

基本上从来没有。大多数网络协议都以“网络字节顺序”定义,即大端。如果您知道另一端有 Intel 架构,您可以使用 little-endian,但您真的知道吗?永远?

于 2012-10-03T10:01:27.703 回答