Remove all string allocations during parsing.
authorrw <me@rwinslow.com>
Thu, 2 Apr 2015 18:56:55 +0000 (11:56 -0700)
committerrw <me@rwinslow.com>
Thu, 2 Apr 2015 18:56:55 +0000 (11:56 -0700)
Change the signature for 'string' getters and settings to use byte
slices instead of strings.

src/idl_gen_go.cpp
tests/GoTest.sh
tests/MyGame/Example/Monster.go
tests/MyGame/Example/Stat.go
tests/go_test.go

index 630fd09..08be810 100644 (file)
@@ -238,7 +238,7 @@ static void GetStringField(const StructDef &struct_def,
   code += " " +  MakeCamel(field.name);
   code += "() " + TypeName(field) + " ";
   code += OffsetPrefix(field) + "\t\treturn " + GenGetter(field.value.type);
-  code += "(o + rcv._tab.Pos)\n\t}\n\treturn \"\"\n";
+  code += "(o + rcv._tab.Pos)\n\t}\n\treturn nil\n";
   code += "}\n\n";
 }
 
@@ -301,7 +301,7 @@ static void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
   code += NumToString(InlineSize(vectortype)) + "))\n";
   code += "\t}\n";
   if (vectortype.base_type == BASE_TYPE_STRING) {
-    code += "\treturn \"\"\n";
+    code += "\treturn nil\n";
   } else {
     code += "\treturn 0\n";
   }
@@ -573,7 +573,7 @@ static void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
 // Returns the function name that is able to read a value of the given type.
 static std::string GenGetter(const Type &type) {
   switch (type.base_type) {
-    case BASE_TYPE_STRING: return "rcv._tab.String";
+    case BASE_TYPE_STRING: return "rcv._tab.ByteVector";
     case BASE_TYPE_UNION: return "rcv._tab.Union";
     case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
     default:
@@ -626,7 +626,7 @@ static std::string GenTypeBasic(const Type &type) {
 static std::string GenTypePointer(const Type &type) {
   switch (type.base_type) {
     case BASE_TYPE_STRING:
-      return "string";
+      return "[]byte";
     case BASE_TYPE_VECTOR:
       return GenTypeGet(type.VectorType());
     case BASE_TYPE_STRUCT:
index ba4835a..877a3ca 100755 (executable)
@@ -43,6 +43,8 @@ GOPATH=${go_path} go test flatbuffers_test \
                      --test.coverpkg=github.com/google/flatbuffers/go \
                      --cpp_data=${test_dir}/monsterdata_test.mon \
                      --out_data=${test_dir}/monsterdata_go_wire.mon \
+                     --test.bench=. \
+                     --test.benchtime=5s \
                      --fuzz=true \
                      --fuzz_fields=4 \
                      --fuzz_objects=10000
index 0ca0c80..a51e429 100644 (file)
@@ -50,12 +50,12 @@ func (rcv *Monster) Hp() int16 {
        return 100
 }
 
-func (rcv *Monster) Name() string {
+func (rcv *Monster) Name() []byte {
        o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
        if o != 0 {
-               return rcv._tab.String(o + rcv._tab.Pos)
+               return rcv._tab.ByteVector(o + rcv._tab.Pos)
        }
-       return ""
+       return nil
 }
 
 func (rcv *Monster) Inventory(j int) byte {
@@ -130,13 +130,13 @@ func (rcv *Monster) Test4Length() int {
        return 0
 }
 
-func (rcv *Monster) Testarrayofstring(j int) string {
+func (rcv *Monster) Testarrayofstring(j int) []byte {
        o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
        if o != 0 {
                a := rcv._tab.Vector(o)
-               return rcv._tab.String(a + flatbuffers.UOffsetT(j * 4))
+               return rcv._tab.ByteVector(a + flatbuffers.UOffsetT(j * 4))
        }
-       return ""
+       return nil
 }
 
 func (rcv *Monster) TestarrayofstringLength() int {
@@ -148,9 +148,7 @@ func (rcv *Monster) TestarrayofstringLength() int {
 }
 
 /// an example documentation comment: this will end up in the generated code
-
 /// multiline too
-
 func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
        o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
        if o != 0 {
index b2c8e3e..936d5ec 100644 (file)
@@ -14,12 +14,12 @@ func (rcv *Stat) Init(buf []byte, i flatbuffers.UOffsetT) {
        rcv._tab.Pos = i
 }
 
-func (rcv *Stat) Id() string {
+func (rcv *Stat) Id() []byte {
        o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
        if o != 0 {
-               return rcv._tab.String(o + rcv._tab.Pos)
+               return rcv._tab.ByteVector(o + rcv._tab.Pos)
        }
-       return ""
+       return nil
 }
 
 func (rcv *Stat) Val() int64 {
index ec48d2f..c1ca165 100644 (file)
@@ -131,7 +131,7 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string,
                fail(FailString("mana", 150, got))
        }
 
-       if got := monster.Name(); "MyMonster" != got {
+       if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
                fail(FailString("name", "MyMonster", got))
        }
 
@@ -209,7 +209,7 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string,
        var monster2 example.Monster
        monster2.Init(table2.Bytes, table2.Pos)
 
-       if got := monster2.Name(); "Fred" != got {
+       if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
                fail(FailString("monster2.Name()", "Fred", got))
        }
 
@@ -267,11 +267,11 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string,
                fail(FailString("Testarrayofstring length", 2, got))
        }
 
-       if got := monster.Testarrayofstring(0); "test1" != got {
+       if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
                fail(FailString("Testarrayofstring(0)", "test1", got))
        }
 
-       if got := monster.Testarrayofstring(1); "test2" != got {
+       if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
                fail(FailString("Testarrayofstring(1)", "test2", got))
        }
 }