Тесты должны повторяться время от времени, не так ли?
:) После исправления некоторых ошибок и добавления моего собственного варианта написания, вот
результаты, которые я получаю при запуске теста на ASUS ZenBook UX305
под управлением Windows 10 (время указано в секундах):
Running tests... 0 1 2
Buffered DataOutputStream 8,14 8,46 8,30
FileChannel alt2 1,55 1,18 1,12
ObjectOutputStream 9,60 10,41 11,68
FileChannel 1,49 1,20 1,21
FileChannel alt 5,49 4,58 4,66
А вот результаты, запущенные на том же компьютере, но с Arch
Linux и порядок переключения методов записи:
Running tests... 0 1 2
Buffered DataOutputStream 31,16 6,29 7,26
FileChannel 1,07 0,83 0,82
FileChannel alt2 1,25 1,71 1,42
ObjectOutputStream 3,47 5,39 4,40
FileChannel alt 2,70 3,27 3,46
Каждый тест записывал файл по 800 Мб. Небуферизованный DataOutputStream взял
долго, поэтому я исключил его из теста.
Как видно, запись с использованием файлового канала по-прежнему бьет все дерьмо
другие методы, но очень важно, является ли байтовый буфер
отображается в памяти или нет. Без отображения памяти запись файла канала
заняло 3-5 секунд:
var bb = ByteBuffer.allocate(4 * ints.length);
for (int i : ints)
bb.putInt(i);
bb.flip();
try (var fc = new FileOutputStream("fcalt.out").getChannel()) {
fc.write(bb);
}
С отображением памяти время было сокращено до 0,8-1,5.
секунд:
try (var fc = new RandomAccessFile("fcalt2.out", "rw").getChannel()) {
var bb = fc.map(READ_WRITE, 0, 4 * ints.length);
bb.asIntBuffer().put(ints);
}
Но учтите, что результаты зависят от порядка. Особенно так далее
Linux. Похоже, что отображенные в память методы не записывают
данные в полном объеме, а скорее выгружает запрос задания в ОС и возвращает
до его завершения. Желательно ли такое поведение или нет
зависит от ситуации.
Отображение памяти также может привести к проблемам OutOfMemory, поэтому оно не
всегда правильный инструмент для
использовать. Предотвратить OutOfMemory при использовании java.nio.MappedByteBuffer .
Вот моя версия кода теста:
https://gist.github.com/bjourne/53b7eabc6edea27ffb042e7816b7830b