Шаблоны для эффективного чтения из Java MemorySegment
Я работаю над использованием Java для чтения (потенциально) больших объемов данных из (потенциально) больших файлов - сценарий представляет собой несжатые изображения из формата файла, такого как HEIF. Скорее всего больше 2G. Письмо — это будущая потребность, но этот вопрос относится к чтению.
Формат HEIF (который является производным от базового формата медиафайлов ISO — ISO/IEC 14496-12) представляет собой «блоки» переменного размера — вы читаете длину и тип блока и выполняете некоторые действия, соответствующие блоку. В моем дизайне я разберу маленькие коробки и оставлю ссылки на объемное хранилище (
mdat
) смещения, чтобы иметь возможность извлекать данные для рендеринга/обработки по запросу.
Я рассматриваю два варианта - несколько MappedByteBuffer (поскольку это ограничено 2G) и один MemorySegment(из файла отображения памяти). Мне не ясно, что, вероятно, будет более эффективным. MappedByteBuffer имеет все хорошие API ByteBuffer, но мне нужно управлять несколькими объектами. MemorySegment будет одной записью, но, похоже, мне нужно создать представления среза, чтобы получить все, что я могу прочитать (например, массив байтов или ByteBuffer), что выглядит как другая версия той же проблемы. Вторичным преимуществом MemorySegment является то, что он может привести к более приятному дизайну, когда мне нужно использовать какой-либо другой не-Java API (например, передача изображений в аппаратный кодировщик для сжатия). У меня также есть скелет MemorySegment, реализованный и читаемый (только с некоторыми грубыми предположениями, что я могу превратить его в один байтовый буфер).
Существуют ли новые шаблоны для эффективного чтения из MemorySegment? В противном случае есть ли что-то, чего мне не хватает в API MemorySegment?
1 ответ
Этому вопросу уже 1,5 года, и он касается API, который все еще развивается и еще не завершен. Вероятно, вы уже приняли решение, но ответить на свой вопрос никогда не поздно.
Я предлагаю ввести новый API FFM в Java. Именно этот API включает в себя . Этот API является заменой JNI и API. Он дает вам гораздо больше контроля над управлением памятью, является более детерминированным, обеспечивает гораздо большее адресное пространство и дает вам больше контроля над чтением и записью примитивов, смещениями, с которыми вы это делаете, и позволяет создавать структурированные методы доступа для связанных примитивных данных. в сегменте.
Однако имейте в виду, что этот API совсем недавно перешел из фазы инкубатора в фазу предварительного просмотра. Это означает, что API близок к завершению, но еще не стабилен. В следующих версиях Java он изменится , поэтому вам придется обновлять свою кодовую базу для каждого нового JDK. Ваш проект не будет иметь обратной и прямой совместимости, пока API не выйдет из состояния предварительного просмотра.
похоже, мне нужно будет создать представления фрагментов, чтобы получить все, что я могу прочитать (например, массив байтов или ByteBuffer)
Это не вариант. В JEP есть несколько примеров .
предоставляет методы прямого доступа, такие какset
(компенсировать),setAtIndex
,get
(смещение) иgetAtIndex
для примитивов — подклассы запечатанного интерфейсаAddressable
, иMemoryAddress
.
Вы также можете использоватьMemoryLayout
иVarHandle
для структурированного доступа.
У вас больше возможностей с новымMemorySegment
API, чем вам предоставляется с помощьюByteBuffer
API.