Aby allocate()
lub allocateDirect()
, oto jest pytanie.
Od kilku lat utknąłem w przekonaniu, że skoro DirectByteBuffer
s to bezpośrednie mapowanie pamięci na poziomie systemu operacyjnego, będzie działać szybciej z wywołaniami get / put niż HeapByteBuffer
s. Aż do tej pory nigdy nie byłem zainteresowany poznaniem dokładnych szczegółów tej sytuacji. Chcę wiedzieć, który z dwóch typów ByteBuffer
jest szybszy i na jakich warunkach.
java
performance
nio
bytebuffer
ROMANIA_engineer
źródło
źródło
SocketChannel
s skonfigurowanych na nieblokowanie. Więc biorąc pod uwagę to, co powiedział @bmargulies,DirectByteBuffer
s będzie działać szybciej na kanałach.Odpowiedzi:
Ron Hitches w swojej doskonałej książce Java NIO wydaje się oferować to, co moim zdaniem może być dobrą odpowiedzią na twoje pytanie:
źródło
Nie ma powodu, aby oczekiwać bezpośrednie bufory być szybszy dostęp do wewnątrz JVM. Ich przewaga pojawia się, gdy przekażesz je do kodu natywnego - na przykład kodu znajdującego się za wszelkiego rodzaju kanałami.
źródło
Nie są. Są po prostu zwykłą pamięcią procesu aplikacji, ale nie podlegają relokacji podczas Java GC, co znacznie upraszcza rzeczy wewnątrz warstwy JNI. To, co opisujesz, dotyczy
MappedByteBuffer
.Wniosek nie wynika z przesłanki; przesłanka jest fałszywa; a wniosek również jest fałszywy. Są szybsze, gdy znajdziesz się w warstwie JNI, a jeśli czytasz i piszesz z tej samej
DirectByteBuffer
, są znacznie szybsze, ponieważ dane nigdy nie muszą w ogóle przekraczać granicy JNI.źródło
Najlepiej wykonać własne pomiary. Szybka odpowiedź wydaje się być taka, że wysyłanie z
allocateDirect()
bufora zajmuje od 25% do 75% mniej czasu niżallocate()
wariant (testowany jako kopiowanie pliku do / dev / null), w zależności od rozmiaru, ale sama alokacja może być znacznie wolniejsza (nawet o współczynnik 100x).Źródła:
Dlaczego dziwna różnica w krzywej wydajności między ByteBuffer.allocate () a ByteBuffer.allocateDirect ()
ByteBuffer.allocateDirect śmiesznie wolno
Kiedy używać Array, Buffer lub Direct Buffer
źródło