Closed MankaranSingh closed 3 years ago
capnproto-java does not attempt to be allcoation-free, so you're going to see some GC costs in any case.
Your code looks efficient to me, if you are reusing bytebuffer
in each loop iteration. The method that you're using calls ByteBuffer.slice()
to avoid copying bytebuffer
:
https://github.com/capnproto/capnproto-java/blob/2f7ce185bb72f98f804bf1e75f6d9f72655da4ed/runtime/src/main/java/org/capnproto/Serialize.java#L163-L165
This means that messageReader
will refer to the same underlying memory as bytebuffer
. You need to be careful, though: if you modify bytebuffer
while messageReader
is still active, then you will corrupt the data in messageReader
.
capnproto-c++ implements a scratchSpace
parameter that makes this kind of buffer reuse a bit easier: https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/serialize.h#L131
capnproto-java does not yet support scratch space reuse for Serialize.read()
, but it's maybe something that could be added in the future.
Thanks for the info! I tried updating byte buffer and reusing same reader. it worked in some cases but crashed in others as you said.
One more thing,
currently I need to call Serialize.write(arrayOutputStream, msgBuilder);
each time I update the message and pass the arrayOutputStream
backed bytebuffer
forward.
is there some bytebuffer
that directly gets updated on changing values of msgBuilder
which I can pass over the wire ?
I suppose Serialize.write(arrayOutputStream, msgBuilder)
needs to copy everytime to a new buffer.
ok, I see that we can directly use segments https://github.com/capnproto/capnproto-java/blob/2f7ce185bb72f98f804bf1e75f6d9f72655da4ed/runtime/src/main/java/org/capnproto/MessageReader.java#L30
my only problem is I cannot send multipart messages over the network due to some reasons :/
That MessageReader
constructor will work even if ByteBuffer[] segmentSlices
has length 1. (Though if you use this instead of Serialize
then you need to handle message framing/delimiting on your own.)
is there some bytebuffer that directly gets updated on changing values of msgBuilder which I can pass over the wire ?
You could write your own implementation of Allocator
to support that
https://github.com/capnproto/capnproto-java/blob/2f7ce185bb72f98f804bf1e75f6d9f72655da4ed/runtime/src/main/java/org/capnproto/Allocator.java#L6-L13
Thanks for all the tips ! Looks like everything I wanted to achieve was already there in the API. Since the messages I use are of fixed size, I computed their size in advanced and then used the MessageBuilder(ByteBuffer firstSegmentSlice);
constructor to provide my own byte buffer of enough length so that list of SegmentSlices
only contains one buffer. I share this buffer over the network so the serialize step / extra copy is totally removed now !
Thanks for the help !
Hi! I have a loop wich recieves buffer from network and deserialize them into capnp reader. I currently use this method:
I am not sure if this is an efficient way or if it allocates new memory every time. Any advice on this ? On how to keep memory usage constant to avoid GC ?