gpt4 book ai didi

python - Python Protobuf 中高效的消息字段设置

转载 作者:太空宇宙 更新时间:2023-11-03 14:05:07 24 4
gpt4 key购买 nike

我正在我正在处理的 Python 项目中使用 Protobuf (v3.5.1)。我的情况可以简化为以下:

// Proto file

syntax = "proto3";

message Foo {
Bar bar = 1;
}

message Bar {
bytes lotta_bytes_here = 1;
}

# Python excerpt
def MakeFooUsingBar(bar):
foo = Foo()
foo.bar.CopyFrom(bar)

我担心 .CopyFrom() 的内存性能(如果我是正确的,它是复制内容,而不是引用)。现在,在 C++ 中,我可以使用如下内容:

Foo foo;
Bar* bar = new Bar();
bar->set_lotta_bytes_here("abcd");
foo.set_allocated_bar(bar);

从生成的源来看,它看起来不需要复制任何内容:

inline void Foo::set_allocated_bar(::Bar* bar) {
::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
if (message_arena == NULL) {
delete bar_;
}
if (bar) {
::google::protobuf::Arena* submessage_arena = NULL;
if (message_arena != submessage_arena) {
bar = ::google::protobuf::internal::GetOwnedMessage(
message_arena, bar, submessage_arena);
}

} else {

}
bar_ = bar;
// @@protoc_insertion_point(field_set_allocated:Foo.bar)
}

Python 中有类似的东西吗?我查看了 Python 生成的源代码,但没有发现任何适用的内容。

最佳答案

说到大stringbytes对象,看来 Protobuf 很好地处理了这种情况。以下通过,这意味着虽然有一个新的 Bar创建对象后,通过引用复制二进制数组(Python bytes 是不可变的,所以这是有意义的):

def test_copy_from_with_large_bytes_field(self):
bar = Bar()
bar.val = b'12345'
foo = Foo()
foo.bar.CopyFrom(bar)

self.assertIsNot(bar, foo.bar)
self.assertIs(bar.val, foo.bar.val)
<小时/>

这解决了我的大问题 bytes目的。但是,如果某人的问题在于嵌套或重复字段,这将无济于事 - 这些字段是逐字段复制的。这确实有道理——如果有人复制一条消息,他们希望两者是独立的。如果不是,对原始消息进行更改将会修改复制的消息(反之亦然)。

如果有任何类似于 C++ 移动语义 ( https://github.com/google/protobuf/issues/2791 ) 或 set_allocated_...() 的内容在Python protobuf中,这可以解决这个问题,但是我不知道有这样的功能。

关于python - Python Protobuf 中高效的消息字段设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48957440/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com