From c127cf78c207ad85b744b13a3011d86cf86f9c51 Mon Sep 17 00:00:00 2001 From: rw Date: Wed, 20 May 2015 12:00:44 -0700 Subject: [PATCH 1/3] Go: CreateString now needs zero allocs. Big speed boost for the typical use case of building with strings. --- go/builder.go | 10 +++++++++- tests/go_test.go | 25 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/go/builder.go b/go/builder.go index 30b09cf9d..c7aa264c7 100644 --- a/go/builder.go +++ b/go/builder.go @@ -281,7 +281,15 @@ func (b *Builder) EndVector(vectorNumElems int) UOffsetT { // CreateString writes a null-terminated string as a vector. func (b *Builder) CreateString(s string) UOffsetT { - return b.CreateByteString([]byte(s)) + b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte) + b.PlaceByte(0) + + l := UOffsetT(len(s)) + + b.head -= l + copy(b.Bytes[b.head:b.head+l], s) + + return b.EndVector(len(s)) } // CreateByteString writes a byte slice as a string (null-terminated). diff --git a/tests/go_test.go b/tests/go_test.go index 2f03ca61c..e3fd51721 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -533,7 +533,14 @@ func CheckByteLayout(fail func(string, ...interface{})) { check([]byte{4, 0, 0, 0, 'm', 'o', 'o', 'p', 0, 0, 0, 0, // 0-terminated, 3-byte pad 3, 0, 0, 0, 'f', 'o', 'o', 0}) - // test 6b: CreateByteString + // test 6b: CreateString unicode + + b = flatbuffers.NewBuilder(0) + b.CreateString("日本語") + check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, // null-terminated, 2-byte pad + 0, 0}) + + // test 6c: CreateByteString b = flatbuffers.NewBuilder(0) b.CreateByteString([]byte("foo")) @@ -1263,10 +1270,10 @@ func BenchmarkBuildGold(b *testing.B) { buf, offset := CheckGeneratedBuild(b.Fatalf) bytes_length := int64(len(buf[offset:])) - reuse_str := []byte("MyMonster") - reuse_test1 := []byte("test1") - reuse_test2 := []byte("test2") - reuse_fred := []byte("Fred") + reuse_str := "MyMonster" + reuse_test1 := "test1" + reuse_test2 := "test2" + reuse_fred := "Fred" b.SetBytes(bytes_length) bldr := flatbuffers.NewBuilder(0) @@ -1275,10 +1282,10 @@ func BenchmarkBuildGold(b *testing.B) { for i := 0; i < b.N; i++ { bldr.Reset() - str := bldr.CreateByteString(reuse_str) - test1 := bldr.CreateByteString(reuse_test1) - test2 := bldr.CreateByteString(reuse_test2) - fred := bldr.CreateByteString(reuse_fred) + str := bldr.CreateString(reuse_str) + test1 := bldr.CreateString(reuse_test1) + test2 := bldr.CreateString(reuse_test2) + fred := bldr.CreateString(reuse_fred) example.MonsterStartInventoryVector(bldr, 5) bldr.PrependByte(4) From 7810fb9ce4b7d3fa3202fc9faaf7e3ee37e1550e Mon Sep 17 00:00:00 2001 From: rw Date: Wed, 20 May 2015 13:42:51 -0700 Subject: [PATCH 2/3] use escape codes here for non-unicode editors --- tests/go_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/go_test.go b/tests/go_test.go index e3fd51721..143c7d618 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -536,7 +536,7 @@ func CheckByteLayout(fail func(string, ...interface{})) { // test 6b: CreateString unicode b = flatbuffers.NewBuilder(0) - b.CreateString("日本語") + b.CreateString("\u65e5\u672c\u8a9e") // chinese from blog.golang.org/strings check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, // null-terminated, 2-byte pad 0, 0}) From 0894c25f2cf9eab62e9abe4410081627faf1cd8b Mon Sep 17 00:00:00 2001 From: rw Date: Wed, 20 May 2015 14:19:49 -0700 Subject: [PATCH 3/3] Improve comment for unicode check. --- tests/go_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/go_test.go b/tests/go_test.go index 143c7d618..070045a1d 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -536,7 +536,11 @@ func CheckByteLayout(fail func(string, ...interface{})) { // test 6b: CreateString unicode b = flatbuffers.NewBuilder(0) - b.CreateString("\u65e5\u672c\u8a9e") // chinese from blog.golang.org/strings + // These characters are chinese from blog.golang.org/strings + // We use escape codes here so that editors without unicode support + // aren't bothered: + uni_str := "\u65e5\u672c\u8a9e" + b.CreateString(uni_str) check([]byte{9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, // null-terminated, 2-byte pad 0, 0})