LINUX.ORG.RU

переместить протобуфные сообщения в C++

 ,


0

1

Имеется протобуфное сообщение (message) X, представляющее собой повторяющееся (repeated) поле другого протобуфного сообщения A. В вектор vectorX типа std::vector<X> из БД был зачитанн массив сообщений X. Во время создания и отправки сообщения А вектор vectorX доступен и существует в программе.

Как наиболее эффективно переместить элементы вектора vectorX (или переставить ссылки на элементы вектора vectorX) в сообщение А.

Собственно работает, но что-то мне кажется это не самое эффективное решение

for(auto iter = vectorX.begin(); iter != vectorX.end(); ++iter) {
  X *x = A.add_x();
  *x = *iter;
}


смотря какой эффективности хочется. Если сэкономить строчек кода то

A.Add(vectorX.begin(), vectorX.end())

если хочется избежать копирования то (коль скоро проты movable) в твоем цикле

A.Reserve(size)
{
*x = std::move(*iter)
}

если message X{} не сильно сложный, то поэлементное копирование через ->set_v может оказаться еще быстрее

Еще как вариант можно накапливать не vector, а сразу RepeatedField [1], который тоже movable.

[1] https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.repeated_field?hl=en

phoenix ★★★★
()
Последнее исправление: phoenix (всего исправлений: 1)
Ответ на: комментарий от phoenix

Спасибо! То, что нужно - под оптимизацией понимал избежание затрат на не нужно копирование ) Разбираюсь

cvprog
() автор топика
Ответ на: комментарий от phoenix

А при добавлении в структуру А повторяющихся полей Х, хранящихся в RepeatedField<X> тоже нужно организовывать цикл?

RepeatedField<X> repeatedX;
// ...
for(auto i = repeatedX.begin(); i != repeatedX.end(); ++i)
{
    X *x = A.add_x();
    *x = std::move(*i);
}
Или мложно прямо сразу все поля запихнуть?

Ну не нашел больше ничего для добавления вектора повторяющихся полей в структуру-сообщение (, нет у них метода Add(iter1, iter2) (у RepeatedField есть).

cvprog
() автор топика
Ответ на: комментарий от phoenix

Я правильно понял, что эффективнее всего по скорости работы так (избегаем лишнего копирования)

// read DB
google::protobuf::RepeatedField<X> arrayX;
for(/*...*/) {
  // read val1, val2, ...
  X *x = arrayX.Add();
  x->set_val1(val1);
  // ...
}

// make message
A a;
*a.mutable_x() = {arrayX.begin(), arrayX.end()};

cvprog
() автор топика
Ответ на: комментарий от cvprog

зачем так сложно-то? Если использовать RepeatedField то сразу так:

google::protobuf::RepeatedField<X>* arrayX = a.mutable_x();
for(/*...*/) {
  // read val1, val2, ...
  X *x = arrayX->Add();
  x->set_val1(val1);
  // ...
}
phoenix ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.