Using CreateVector seems to be very slow for types wider than 1 byte. For example, see this (ignore the repository name, that's just from an old issue): https://github.com/cberner/flatbuffer_leak
Steps to repro:
1) git clone https://github.com/cberner/flatbuffer_leak
2) cd flatbuffer_leak && docker build .
3) docker run --rm
For me this produces:
Using CreateUninitializedVector: 0.319512
Using CreateVector: 3.27558
It doesn't use memcpy underneath because we have go through PushElement that does correct endianess swapping when on a big-endian machine and it deals with non-scalars (offsets) that need are fixed to their location when serialized.
This situation would be good to special-case however. We could overload CreateVector for Offset<T> and T much like the underlying PushElement, and then for the T case we could use an #if FLATBUFFERS_LITTLEENDIAN to directly use PushBytes (memcpy).
Care to make a PR?
Nice find. I agree we should pay the readability cost to make this as optimal as possible on little-endian platforms.
Btw, I remember seeing this a while back:
https://github.com/thekvs/cpp-serializers
When I saw it, I was a little confused why capnproto was so different from flatbuffers, but I didn't dig into it at all. I suspect this exact ~bug~ overhead is contributing to the performance difference, since the benchmark is creating a vector of longs and a vector of strings over and over.
@aardappel yep, here you go. Hope I did it right!
https://github.com/google/flatbuffers/pull/4355
Most helpful comment
@aardappel yep, here you go. Hope I did it right!
https://github.com/google/flatbuffers/pull/4355