Круговой байтовый буфер Java, расширяющий java.nio.ByteBuffer - PullRequest
9 голосов
/ 04 марта 2011

Каждая реализация кольцевого байтового буфера Java, на которую я видел ссылки на SO и в других местах, не расширяет java.nio.ByteBuffer, что для меня необходимо для использования с SocketChannel. Кто-нибудь знает о реализации с открытым исходным кодом, которая расширяет ByteBuffer. Я попытался пойти по пути написания своих собственных, но застрял, когда понял, что положение и остальные функции являются окончательными, и я собирался переопределить их, чтобы приспособиться к заголовку и предотвратить исключения переполнения буфера. При отправке 5000 сообщений по каналу сокета, при этом каждый, кто мне нужен для копирования содержимого в начало линейного буфера, добавляет около 450 мс или 90 мкс на сообщение (которое содержит 10 пакетов, то есть 9 мкс на пакет). Прямо сейчас единственный способ, который я могу придумать, - это переопределить каждый метод и переписать все. Есть идеи?

Ответы [ 4 ]

6 голосов
/ 04 марта 2011

Вы не можете расширить java.nio.ByteBuffer , просто так. C-tor является частным пакетом. Это НЕ будет работать, потому что основная идея - передать адрес в некоторый C-код. Также вы не можете ничего переопределить, так как многие методы являются окончательными. ByteBuffers были разработаны для скорости, и некоторые решения могут выглядеть странными, но они в порядке.

java.nio.channels.GatheringByteChannel и java.nio.channels.ScatteringByteChannel стоит попробовать, хотя их реализация зависит от реализации (native C).

6 голосов
/ 04 марта 2011

Вместо создания циклического буфера вы можете сделать буфер намного больше, чем одно сообщение.Скажем, максимальный размер сообщения составляет N байтов.Создайте буфер размером 100 * N байтов, которые являются компактными () ByteBuffer только когда осталось меньше N байтов.Это уменьшит объем копирования в 100 раз.

Другая оптимизация заключается в сжатии () ByteBuffer всякий раз, когда нет оставшихся данных, поскольку это очень быстро.

2 голосов
/ 09 апреля 2013

Мы могли бы попробовать это, так как это лицензия Apache

https://svn.apache.org/repos/asf/etch/releases/release-1.0.0/util/src/main/java/etch/util/CircularByteBuffer.java

0 голосов
/ 29 января 2014

Я бы использовал метод ByteBuffer.wrap (). Посмотрев быстро на реализацию Cisco, которую ранее разместил г-н Дин Хиллер, вы можете заменить put () на getWriteBuffer (), который вернет вам ByteBuffer, который упаковывает часть в буфер, который он может записать.

Та же логика может быть применена к части чтения.

Преимуществом этого является отсутствие сжатия, которое может быть дорогостоящим в зависимости от количества байтов в ByteBuffer за счет усложнения логики синтаксического анализа: вы можете получить первую часть вашего сообщения для ByteBuffer, которая оборачивает последнюю область нижележащего кольцевого буфера. Чтобы получить вторую часть вашего сообщения, необходимо еще одно чтение, чтобы получить байтовый массив в начале циклического буфера, заключенного в другой ByteBuffer.

...