使用memcpy将std::vector复制到protobuf中的重复字段
Copy a std::vector to a repeated field from protobuf with memcpy
首先我有一个简单的protobuf文件
message messagetest
{
...
repeated float samples = 6;
....
}
它用这种方法创建了一个头文件
//repeated float samples = 6;
inline int samples_size() const;
inline void clear_samples();
static const int kSamplesFieldNumber = 6;
inline float samples(int index) const;
inline void set_samples(int index, float value);
inline void add_samples(float value);
inline const ::google::protobuf::RepeatedField< float >& samples() const;
inline ::google::protobuf::RepeatedField< float >* mutable_samples();
我基本上要做的是在for循环中一个接一个地复制所有数据。
int main(int argc, char** argv)
{
messagetest fMessage;
vector<float> fData (1000, 0);
// Create 1000 random values
for (int i = 0; i < fData.size(); i++)
{
fData[i] = rand() % 1001;
}
for (int j = 0; j < fData.size(); j++)
{
fMessage.add_samples(fData[j]);
}
return 0;
}
但我想使用类似memcpy的方法来加速复制过程。这只是我想到的一个想法。如果完全错误,请纠正我。头文件中的最后一个声明是:
inline ::google::protobuf::RepeatedField< float >* mutable_samples();
我不知道这种方法的作用(缺乏技巧(。但它看起来有点像矢量。也许这就是解决我问题的办法。如果是这样的话,我不知道如何实现它。
因为这还没有出现,而且我喜欢一行代码:
*fMessage.mutable_samples() = {fData.begin(), fData.end()};
我找到了将矢量复制到重复字段的最短方法,如下所示:
google::protobuf::RepeatedField<float> data(fData.begin(), fData.end());
fMessage.mutable_samples()->Swap(&data);
它可能也比您的更快,因为它避免了初始迭代并将值设置为0。
@mgild的答案将隐式调用RepeatedField(Iter begin, Iter end)
构造函数来创建一个要移动分配的临时构造函数。与@nazgul的答案相同,显式创建一个临时RepeatedField并交换它。
更简单的是,避免创建新对象的方法是:
fMessage.mutable_samples()->Add(fData.begin(), fData.end())
如果samples
字段尚未为空,则可以先调用Clear
方法。
在内部,它使用std::copy
(只要fData
是一个前向迭代器(,所以它的速度将与您提出的任何memcpy实现一样快。
作为@mgild发布的优秀答案的替代方案,Assign
也可以在这种情况下使用,因此数据在移动之前不会被复制到临时位置。
fMessage.mutable_samples()->Assign(fData.begin(), fData.end())
归功于Marek R的回答
fMessage.mutable_samples()
返回样本的指针数组:[*sample1,*sample2,sample3,…].
&fData[0]
是fData的第一个元素的地址。
memcpy(fMessage.mutable_samples()->mutable_data(),
&fData[0],
sizeof(float)*fData.size());
所以我认为上面的代码不能成功地将数据从fData填充到fMessage。这完全错了!
相关文章:
- 将结构字段的类型展开为可变模板参数
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- protobuf,如何在protobuf消息中遍历所有集合字段,我不知道详细信息?(C++)
- 如何将必需的 protobuf 字段设置为其默认值?
- Protobuf序列化长度在使用不同的字段值时会有所不同
- 使用反射在 protobuf 中设置重复字段
- 附加Protobuf重复字段
- 为什么 c++ 中没有重复的 protobuf 字段的 Set 方法
- 协议缓冲区(protobuf)v3.0.0-阿尔法-2中的可选字段和约束
- 收到的Protobuf对象没有所有字段
- 如何在 protobuf 中使用反射将预分配的消息设置为字段C++
- Protobuf:如何在C++中处理嵌套(自定义)可选字段
- 遍历所有字段并在 protobuf 消息中获取它们的值
- protobuf-net 缺少可选字段的has_函数
- 如何在解析文本格式的 protobuf 消息时忽略错误的字段
- 解决由于C++而导致的谷歌protobuf中的枚举字段命名限制的解决方案
- Protobuf 声明我缺少必填字段,而我显然不是
- 打印Protobuf消息时省略字段
- 使用memcpy将std::vector复制到protobuf中的重复字段
- Protobuf必填字段和默认值