Операция ввода / вывода на каналах с использованием ByteBuffer - сравнение производительности - PullRequest
3 голосов
/ 30 октября 2011

Я хочу выполнить операцию ввода / вывода на каналах, используя ByteBuffer.Наконец, я предложил три решения:

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

Метод 1: использование hasRemaining()

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

Метод 2: использование compact()

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

Метод3: гибридная модель

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

Вопрос в том, какой метод имеет наибольшую производительность и пропускную способность?

Ответы [ 2 ]

3 голосов
/ 30 октября 2011

Зачем вам вообще нужно использовать compact()?- Это может включать многократное копирование большого количества данных.

Ваш первый метод - это правильный путь, если у вас нет серьезных оснований для повторного чтения до того, как будут записаны все ранее прочитанные данные.

Да, и между прочим: Если вы только копируете данные из одного файла в другой, взгляните на transferTo() или transferFrom().Это наиболее эффективный способ копирования файлов, поскольку может использовать очень эффективные операции базовой ОС, например, DMA.

(Edit: TransferTo () и т. Д., Конечно, делают не нужен какой-либо ByteBuffer, смешанные две мысли там:))

1 голос
/ 30 октября 2011

Чтобы максимизировать производительность, я предлагаю вам использовать прямой буфер размером около 32 КБ.Эти размеры от 16 КБ до 64 КБ часто работают лучше всего в зависимости от вашей системы.

Для файловых каналов должна быть возможность читать / записывать все данные каждый раз, поэтому я не думаю, что различные методылюбая разница.Это может иметь значение при чтении / записи в Socket Channels.

...