commit 35a95f054c7849fae3a602407a2d33583a48624f
parent 73600a98c556ff2da24a90f556188b676eaaff31
Author: francoispqt <francois@parquet.ninja>
Date: Thu, 20 Dec 2018 15:57:23 +0800
create new buffer before releasing only when using marshal syntax - decode syntax does not need to create a new buffer as it writes directly to the reader
Diffstat:
4 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/encode.go b/encode.go
@@ -34,7 +34,12 @@ func MarshalJSONArray(v MarshalerJSONArray) ([]byte, error) {
enc.writeByte('[')
v.(MarshalerJSONArray).MarshalJSONArray(enc)
enc.writeByte(']')
- defer enc.Release()
+
+ defer func() {
+ enc.buf = make([]byte, 0, 512)
+ enc.Release()
+ }()
+
return enc.buf, nil
}
@@ -61,7 +66,12 @@ func MarshalJSONArray(v MarshalerJSONArray) ([]byte, error) {
func MarshalJSONObject(v MarshalerJSONObject) ([]byte, error) {
enc := BorrowEncoder(nil)
enc.grow(512)
- defer enc.Release()
+
+ defer func() {
+ enc.buf = make([]byte, 0, 512)
+ enc.Release()
+ }()
+
return enc.encodeObject(v)
}
@@ -91,6 +101,11 @@ func marshal(v interface{}, any bool) ([]byte, error) {
err error
)
+ defer func() {
+ enc.buf = make([]byte, 0, 512)
+ enc.Release()
+ }()
+
buf, err = func() ([]byte, error) {
switch vt := v.(type) {
case MarshalerJSONObject:
@@ -133,8 +148,6 @@ func marshal(v interface{}, any bool) ([]byte, error) {
return nil, InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
}
}()
-
- enc.Release()
return buf, err
}
diff --git a/encode_object.go b/encode_object.go
@@ -44,7 +44,7 @@ func (enc *Encoder) EncodeObjectKeys(v MarshalerJSONObject, keys []string) error
}
func (enc *Encoder) encodeObject(v MarshalerJSONObject) ([]byte, error) {
- enc.grow(500)
+ enc.grow(512)
enc.writeByte('{')
if !v.IsNil() {
v.MarshalJSONObject(enc)
diff --git a/encode_pool.go b/encode_pool.go
@@ -35,7 +35,7 @@ func NewEncoder(w io.Writer) *Encoder {
func BorrowEncoder(w io.Writer) *Encoder {
enc := encPool.Get().(*Encoder)
enc.w = w
- enc.buf = make([]byte, 0, 512)
+ enc.buf = enc.buf[:0]
enc.isPooled = 0
enc.err = nil
enc.hasKeys = false
diff --git a/encode_pool_test.go b/encode_pool_test.go
@@ -1 +1,32 @@
package gojay
+
+import (
+ "fmt"
+ "log"
+ "strconv"
+ "testing"
+ "time"
+)
+
+func TestConcurrencyMarshal(t *testing.T) {
+ var f = func(num int, t *testing.T) {
+ for {
+ b, err := Marshal(num)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ s := string(b)
+ if n, err := strconv.Atoi(s); err != nil || n != num {
+ t.Error(fmt.Errorf(
+ "caught race: %v %v", s, num,
+ ))
+ }
+ }
+ }
+
+ for i := 0; i < 100; i++ {
+ go f(i, t)
+ }
+ time.Sleep(2 * time.Second)
+}