为了账号安全,请及时绑定邮箱和手机立即绑定

与 protobuf 相比,Flatbuffer 序列化性能较慢

与 protobuf 相比,Flatbuffer 序列化性能较慢

Go
交互式爱情 2022-05-18 16:36:09
通过以下 IDL 文件,我的目的是测量 Flatbuffer 的序列化速度。我正在使用 golang 进行分析namespace MyFlat;struct Vertices {    x : double;    y  :double;}table Polygon  {    polygons : [Vertices];}table Layer {    polygons : [Polygon];}root_type Layer;这是我为计算编写的代码包主import (    "MyFlat"    "fmt"    "io/ioutil"    "log"    "strconv"    "time"    flatbuffers "github.com/google/flatbuffers/go")func calculation(size int, vertices int) {    b := flatbuffers.NewBuilder(0)    var polyoffset []flatbuffers.UOffsetT    rawSize := ((16 * vertices) * size) / 1024    var vec1 flatbuffers.UOffsetT    var StartedAtMarshal time.Time    var EndedAtMarshal time.Time    StartedAtMarshal = time.Now()    for k := 0; k < size; k++ {        MyFlat.PolygonStartPolygonsVector(b, vertices)        for i := 0; i < vertices; i++ {            MyFlat.CreateVertices(b, 2.0, 2.4)        }        vec1 = b.EndVector(vertices)        MyFlat.PolygonStart(b)        MyFlat.PolygonAddPolygons(b, vec1)        polyoffset = append(polyoffset, MyFlat.PolygonEnd(b))    }    MyFlat.LayerStartPolygonsVector(b, size)    for _, offset := range polyoffset {        b.PrependUOffsetT(offset)    }    vec := b.EndVector(size)    MyFlat.LayerStart(b)    MyFlat.LayerAddPolygons(b, vec)    finalOffset := MyFlat.LayerEnd(b)    b.Finish(finalOffset)    EndedAtMarshal = time.Now()    SeElaprseTime := EndedAtMarshal.Sub(StartedAtMarshal).String()    mybyte := b.FinishedBytes()    file := "/tmp/myflat_" + strconv.Itoa(size) + ".txt"    if err := ioutil.WriteFile(file, mybyte, 0644); err != nil {        log.Fatalln("Failed to write address book:", err)    }}问题是我发现与具有类似 idl 的 protobuff 相比,它的序列化速度非常慢。对于 3M 多边形序列化,它需要将近 4.1167037 秒。在 protobuf 中占一半的位置。flatbuf 的反序列化时间非常短(以微秒为单位)。在 protobuf 中它相当高。但是,如果我同时添加两个 flatbuf,性能仍然会降低。您是否看到任何优化的序列化方式。Flatbuffer 有一个方法 createBinaryVector 用于字节向量,但没有直接的方法可以从现有的用户定义类型向量序列化多边形向量。
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

您给的时间是用于序列化、反序列化还是两者兼而有之?

您的反序列化代码可能完全由fmt.Println. 您为什么不在计时完成后进行sum += objVertices.X() + objVertices.Y()打印?sum你能拉出objVertices := &MyFlat.Vertices{}循环吗?

您没有发布您的 protobuf 代码。您是否在计时中包括创建正在序列化的对象树的时间(在 Protobuf 中使用但在 FlatBuffers 中不需要)?同样,您是否进行了至少 1000 倍左右的定时(反)序列化,因此您可以在比较中包括 GC 成本(Protobuf 分配大量对象,FlatBuffers 分配很少/无)?

如果执行上述操作后仍然较慢,请在 FlatBuffers github 问题上发帖,Go 端口的作者可能会提供进一步的帮助。确保发布两个系统的完整代码和完整的时间。

一般注意:FlatBuffers 的设计是这样的,它将与 C/C++ 中的 Protobuf 产生最大的性能差距。也就是说,它在 Go 中也应该快得多。然而,Go 有一些不幸的事情阻止它最大限度地发挥性能潜力。


查看完整回答
反对 回复 2022-05-18
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

   b := flatbuffers.NewBuilder(0)

我不确定 Go for flatbuffers 中的“自动增长”行为是什么,但我很确定要求缓冲区自动增长不是首选模式。您可以在初始化缓冲区后尝试进行相同的时序比较flatbuffers.NewBuilder(moreBytesThanTheMessageNeeds)吗?


查看完整回答
反对 回复 2022-05-18
  • 2 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号