【问题标题】:I/O Operation On Channels Using ByteBuffer - Performance Comparision使用 ByteBuffer 对通道进行 I/O 操作 - 性能比较
【发布时间】:2011-12-18 04:04:02
【问题描述】:

我想使用ByteBuffer 对通道执行 I/O 操作。最后我想出了三个解决方案:

FileChannel inChannel = new FileInputStream("input.txt").getChannel();
FileChannel outChannel = new FileOutputStream("output.txt").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024 * 1024);

方法一:使用hasRemaining()

while (inChannel.read(buf) != -1) {
    buf.flip();    
    while (buf.hasRemaining()) {
        outChannel.write(buf);
    }    
    buf.clear();
}

方法二:使用compact()

while (inChannel.read(buf) != -1 || buf.position() > 0) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}

方法三:混合模型

while (inChannel.read(buf) != -1) {
    buf.flip();
    outChannel.write(buf);
    buf.compact();
}
// final flush of pending output
while (buf.hasRemaining())
    outChannel.write(buf);

问题是:哪种方法的性能和吞吐量最高?

【问题讨论】:

标签: java performance bytebuffer channels


【解决方案1】:

您为什么要使用compact()? - 它可能涉及重复复制大量数据。

如果您没有严重的理由在所有先前读取的数据被写入之前执行另一次读取,则您的第一种方法是可行的方法。

哦,顺便说一句:如果您只是想将数据从一个文件复制到另一个文件,请查看transferTo()transferFrom()。这是文件复制最高效的方式,因为它可能使用底层操作系统的非常高效的操作,例如 DMA。

(编辑:transferTo() 等当然需要任何 ByteBuffer,混合了两种想法:))

【讨论】:

    【解决方案2】:

    为了最大限度地提高性能,我建议您尝试使用大约 32 KB 的直接缓冲区。根据您的系统,16 KB 到 64 KB 的大小通常效果最佳。

    对于文件通道,它应该能够每次都读取/写入所有数据,所以我认为各种方法不会有任何区别。但是,在读取/写入 Socket Channels 时会有所不同。

    【讨论】:

    猜你喜欢
    • 2020-04-05
    • 2012-10-11
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 2010-12-31
    • 2020-07-28
    相关资源
    最近更新 更多