Предположим, у меня есть прямой ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
и предположим, я передаю буфер к AsynchronousSocketChannel для чтения блоков данных от этого сокета до X байт в то время (1024 в примере здесь).
Передача времени сокета в напрямую ByteBuffer является фантастическим, потому что все это происходит в памяти собственной ОС; Я не прошел через «гематоэнцефалический барьер» JVM еще ...
ВОПРОС
Предполагая, что моя работа состоит в том, чтобы просканировать все прочитанные байты снова из прямого буфера байт, что самый быстрый способ для этого?
Первоначально я спросил: «... используя sun.misc.Unsafe», но, возможно, это неправильное предположение.
ВОЗМОЖНЫЕ ПОДХОДЫ
В настоящее время я вижу три подхода и один я самым любопытным является # 3:
- (DEFAULT) Использование ByteBuffer-х bulk-get тянуть байты непосредственно из родного пространства ОС в внутренний байт [1024].
- (UNSAFE) Используйте операторы Unsafe's getByte, чтобы вытащить значения непосредственно из ByteBuffer, пропустив все проверки границ стандартных операций ByteBuffer. Ответ Питера Лоури here, по-видимому, предполагал, что эти исходные собственные методы в Unsafe даже могут быть оптимизированы компилятором JIT («intrinsics») на отдельные машинные команды, что приведет к еще более фантастическому времени доступа. (=== UPDATE === интересно, похоже, что базовый класс DirectByteBuffer делает именно это с get/put ops для тех, кто интересуется.)
- (BANANAS) В некотором роде способов преступности против человечества, используя Unsafe, может ли я copy the memory region прямого ByteBuffer на тот же адрес памяти, что мой байт [1024] существует внутри виртуальной машины и только начинает получать доступ к массиву с использованием стандартных индексов int? (Это делает предположение о том, что «CopyMemory» операция может потенциально сделать что-то сказочно оптимизированное на уровне операционной системы.
Это происходит со мной, что в предположении CopyMemory операцию делает именно то, что она рекламирует, даже в более -оптимальное пространство ОС, что описанный выше подход № 2, вероятно, по-прежнему наиболее оптимизирован, так как я не создаю дубликаты буфера перед началом его обработки.
Это отличается от вопроса «can I use Unsafe to iterate over a byte[] faster?», поскольку я даже не планирование по извлечению байтов в байт [] внутренне, если нет необходимости.
Спасибо за время; просто любопытно, если кто-нибудь (Питер?) получил орехи с Unsafe, чтобы сделать что-то вроде этого.
Не знал о «внутреннем» свойстве методов ByteBuffer; вы имеете в виду «родные» методы в классе DirectBuffer? В этом случае это будет делать то, что № 2 будет делать в моем сообщении выше, так что это отличная новость. –
@RiyadKalla intrinsic! = Native. Внутренние методы «жестко закодированы» в JVM. – assylias
@assylias Я понимаю; Я был (неправильно) со ссылкой на то, что, как я понял, был «родным» методом в классе DirectByteBuffer impl (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java /nio/DirectByteBuffer.java), но теперь, когда я смотрю на него, я вижу, что нет «родных» методов, он просто использует Unsafe для выполнения этих операций. Я ошибаюсь, благодарю вас за улов. –