title: Flatbuffer serialization performance is slow compared to protobuf
body: <p>With following IDL files my intention is to measure the serialization speed of Flatbuffer . I am using golang for my analysis </p>
  
  <pre><code>namespace MyFlat;
  
  struct Vertices {
      x : double;
      y  :double;
  
  }
  table Polygon  {
  
      polygons : [Vertices];
  }
  
  table Layer {
  
      polygons : [Polygon];
  }
  root_type Layer;
  </code></pre>
  
  <p>Here is the code I have written for calculation </p>
  
  <p>package main</p>
  
  <pre><code>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 &lt; size; k++ {
  
          MyFlat.PolygonStartPolygonsVector(b, vertices)
  
          for i := 0; i &lt; 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)
      }
  
      StartedAt := time.Now()
  
      layer := MyFlat.GetRootAsLayer(mybyte, 0)
  
      size = layer.PolygonsLength()
      obj := &amp;MyFlat.Polygon{}
      layer.Polygons(obj, 1)
  
      for i := 0; i &lt; obj.PolygonsLength(); i++ {
          objVertices := &amp;MyFlat.Vertices{}
          obj.Polygons(objVertices, i)
          fmt.Println(objVertices.X(), objVertices.Y())
      }
  
      EndedAt := time.Now()
      DeElapseTime := EndedAt.Sub(StartedAt).String()
      fmt.Println(size, ",", vertices, ", ", SeElaprseTime, ",", DeElapseTime, ",", (len(mybyte) / 1024), ",", rawSize)
  }
  
  func main() {
  
      data := []int{500000, 1000000, 1500000, 3000000, 8000000}
  
      for _, size := range data {
          //calculation(size, 5)
          //calculation(size, 10)
          calculation(size, 20)
  
      }
  }
  </code></pre>
  
  <p>Problem is I find it serialization is quite slow compared to protobuff  with similar idl.</p>
  
  <p>For 3M polygons serialization its taking almost 4.1167037s. Where in protobuf its taking half. Deserilization time for flatbuf is very less (in micro sec). In protobuf its quite high. But still if I add both flatbuf performance is lower.</p>
  
  <p>Do you see any optimized way to serialize it. Flatbuffer is having a method createBinaryVector for byte vector but there is no direct way to serialize  vector of polygon from a existing a user defined type vector.</p>
  
  <p>I am adding protobuf code also</p>
  
  <p>syntax = 'proto3';</p>
  
  <pre><code>package myproto; 
  message Polygon {
                   repeated double v_x = 1 ;
                   repeated  double v_y = 2 ;
              }
  message CADData {
  
  
         repeated Polygon polygon = 1;
          string layer_name = 2;
  } 
  </code></pre>
  
  <p>Go Code with protobuf</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "io/ioutil"
      "log"
      "math/rand"
      "myproto"
      "strconv"
      "time"
  
      "github.com/golang/protobuf/proto"
  )
  
  func calculation(size int, vertices int) {
      var comp []*myproto.Polygon
      var vx []float64
      var vy []float64
      for i := 0; i &lt; vertices; i++ {
          r := 0 + rand.Float64()*(10-0)
          vx = append(vx, r)
          vy = append(vy, r/2)
  
      }
      rawSize := ((16 * vertices) * size) / 1024
      StartedAtMarshal := time.Now()
  
      for i := 0; i &lt; size; i++ {
          comp = append(comp, &amp;myproto.Polygon{
  
              VX: vx,
              VY: vy,
          })
      }
      pfs := &amp;myproto.CADData{
          LayerName: "Layer",
          Polygon:   comp,
      }
      data, err := proto.Marshal(pfs)
      if err != nil {
          log.Fatal("marshaling error: ", err)
      }
      EndedAtMarshal := time.Now()
      SeElaprseTime := EndedAtMarshal.Sub(StartedAtMarshal).String()
      file := "/tmp/myproto_" + strconv.Itoa(size) + ".txt"
      if err := ioutil.WriteFile(file, data, 0644); err != nil {
          log.Fatalln("Failed to write address book:", err)
      }
  
      StartedAt := time.Now()
  
      serialized := &amp;myproto.CADData{}
      proto.Unmarshal(data, serialized)
      EndedAt := time.Now()
      DeElapseTime := EndedAt.Sub(StartedAt).String()
      fmt.Println(size, ",", vertices, ", ", SeElaprseTime, ",", DeElapseTime, ",", (len(data) / 1024), ",", rawSize)
  }
  
  func main() {
      data := []int{500000, 1000000, 1500000, 3000000, 8000000}
      for _, size := range data {
          //  calculation(size, 5)
          //calculation(size, 10)
          calculation(size, 20)
  
      }
  }
  </code></pre>