猿问

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

通过以下 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 用于字节向量,但没有直接的方法可以从现有的用户定义类型向量序列化多边形向量。


交互式爱情
浏览 113回答 2
2回答

噜噜哒

您给的时间是用于序列化、反序列化还是两者兼而有之?您的反序列化代码可能完全由fmt.Println.&nbsp;您为什么不在计时完成后进行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 有一些不幸的事情阻止它最大限度地发挥性能潜力。

30秒到达战场

&nbsp;&nbsp;&nbsp;b&nbsp;:=&nbsp;flatbuffers.NewBuilder(0)我不确定 Go for flatbuffers 中的“自动增长”行为是什么,但我很确定要求缓冲区自动增长不是首选模式。您可以在初始化缓冲区后尝试进行相同的时序比较flatbuffers.NewBuilder(moreBytesThanTheMessageNeeds)吗?
随时随地看视频慕课网APP

相关分类

Go
我要回答