я использую flatbuffers и nng.используя FB я создаю разделенные буферы и добавляю их в nng msg.Я хотел исключить это копирование FB в NNG.
Для этого я написал собственный распределитель, как показано ниже.
class CustomAllocator : public flatbuffers::Allocator
{
private:
nng_msg *m_nng_msg = nullptr;
public:
~CustomAllocator()
{
if (m_nng_msg) {
nng_msg_free(m_nng_msg);
m_nng_msg = nullptr;
}
}
nng_msg *get() { return m_nng_msg; }
nng_msg *release()
{
nng_msg *t_nng_msg = m_nng_msg;
m_nng_msg = nullptr;
return t_nng_msg;
}
uint8_t *allocate(size_t size) override
{
if (nng_msg_alloc(&m_nng_msg, size) != 0) {
return nullptr;
}
return static_cast<uint8_t *>(nng_msg_body(m_nng_msg));
}
void deallocate(uint8_t *p, size_t size) override
{
if (m_nng_msg) {
nng_msg_free(m_nng_msg);
m_nng_msg = nullptr;
}
}
};
, а затем прикрепил его к FB, как показано ниже
CustomAllocator allocator;
flatbuffers::FlatBufferBuilder builder(1024, &allocator);
... fill using builder
nng_msg *msg = allocator.get();
nng_msg_trim(msg, nng_msg_len(msg) - builder.GetSize()); // this is required as FB adds data to the end of the buffer, i checked the *_trim and it does not do realloc
nng_msg_set_pipe(msg, pipe);
nng_sendmsg(s, msg, 0);
для случая двойной копии, я использую его так:
flatbuffers::FlatBufferBuilder builder(1024);
... fill using builder
nng_msg *msg = nullptr;
nng_msg_alloc(&msg, 0);
nng_msg_append(msg, builder.GetBufferPointer(), builder.GetSize());
nng_msg_set_pipe(msg, pipe);
nng_sendmsg(s, msg, 0);
Я ожидал, что нет-копия будет немного лучше, чем двойная копия.Но когда я запускаю тесты, я получаю разные результаты.
Так что мне интересно, что может быть причиной такого поведения?
каждый сценарий запускался 20 раз, чтобы получить среднее время.
Message Size 180 bytes
Message Count 20000 80000 100000
no-copy copy no-copy copy no-copy copy
time in ms 198 185 809 784 997 950
std-dev 47 44 85 66 72 83