Почему FileChannel работает лучше, чем MemoryMappedBuffer?

Я читаю файл размером 50 ГБ (только для чтения), используя несколько потоков, при этом каждый поток читает последовательный сегмент из файла. Я попробовал два подхода

  • Использование файлового канала
  • Использование MemoryMappedBuffer, полученного из FileChannel

Я ожидал, что MemoryMappedBuffer превзойдет FileChannel, но FileChannel стабильно работает примерно на 30% лучше.

Я ищу объяснение. Я сопоставляю память по 1 ГБ за раз, и как только она заканчивается, я сопоставляю еще 1 ГБ.

Моя среда: платформа Windows 7, 64-разрядный процессор xeon 2,7 ГГц, 2 процессора.


person Sid    schedule 09.11.2016    source источник
comment
Платформа Windows 7 64-разрядная версия xeon 2,7 ГГц 2 процессора   -  person Sid    schedule 09.11.2016
comment
Только сколько у тебя оперативной памяти? Если у вас не более 50 ГБ, FileChannel должен работать быстрее (чем при использовании виртуальной памяти).   -  person ebyrob    schedule 09.11.2016
comment
Какова цель чтения всего 50-гигабайтного файла? Не могли бы вы обработать его по частям, чтобы он подходил к вашему барану?   -  person walkeros    schedule 09.11.2016
comment
32 ГБ оперативной памяти, но доступно только 20   -  person Sid    schedule 09.11.2016
comment
@walkeros Я тестирую способ чтения этого файла как можно скорее   -  person Sid    schedule 09.11.2016
comment
Может быть интересно сравнить FileInputStream и/или FileOutputStream с результатами, которые вы видите здесь. Я считаю, что каналы в java.nio всегда были своего рода синонимом буферизации, тогда как более старые классы java.io Stream иногда работали против «голого железа» ввода-вывода ОС. Подробнее см. в этой ветке: stackoverflow .com/questions/1605332/   -  person ebyrob    schedule 09.11.2016
comment
@Sid: чем вы сами доказали, что чтение всего файла в память - плохая идея с точки зрения производительности ... на самом деле вам не следует этого делать, если в этом нет необходимости. Вы должны добавить в свой тест тест, в котором вы читаете свой файл по частям, используя два упомянутых вами метода, и это может привести вас к совершенно другому мнению о том, что является самым быстрым.   -  person walkeros    schedule 09.11.2016
comment
@walkeros Я пытался уменьшить длину отображаемого файла памяти до 16 МБ за раз, а затем попробовал 200 МБ и в обоих случаях получил одинаковые результаты.   -  person Sid    schedule 09.11.2016
comment
Также обратите внимание, что в Java можно сопоставлять только байты Integer.MAXVALUE с памятью, поэтому я не сопоставляю все 50 ГБ одновременно.   -  person Sid    schedule 09.11.2016
comment
Я вижу и предполагаю, что вы открываете файл в режиме READ_ONLY?   -  person walkeros    schedule 09.11.2016
comment
Да исправить. Хотя мне интересно, может ли это быть из-за того, что мне нужно явно вызвать метод загрузки MappedByteBuffer, чтобы загрузить содержимое в физическую память, чтобы предотвратить слишком много ошибок страниц. Я попробую сделать это дальше.   -  person Sid    schedule 09.11.2016
comment
Если, как это звучит, вы выполняете последовательный ввод-вывод, нет никаких причин, по которым MappedByteBuffer должен быть быстрее, чем FileChannel или даже FileInputStream, и есть множество причин, по которым он должен быть медленнее.   -  person user207421    schedule 09.11.2016
comment
@EJP Я полагаю, вы заранее оплачиваете стоимость ошибок страниц, отображая файл в памяти и принудительно загружая физическую память, а не последовательную буферизацию через FileChannel?   -  person Sid    schedule 09.11.2016


Ответы (1)


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

person bmargulies    schedule 09.11.2016
comment
Точно, буфер памяти просто больше накладных расходов (если относительно небольшие накладные расходы). - person ebyrob; 09.11.2016
comment
Согласен, но почему тогда MemoryMappedBuffer медленнее? - person Sid; 09.11.2016
comment
Думаю, я имею в виду, что накладные расходы на ошибку страницы составляют около 30%, что кажется слишком большим. - person Sid; 09.11.2016
comment
Что ж, вам понадобится эксперт по Windows, который прибудет на место происшествия. - person bmargulies; 09.11.2016