Przeglądaj źródła

marshal: use passed in byte slice if available. (#1167)

We don't aloways need to allocate a new slice to unmarshal into when the
passed in one is available.

```
name                old time/op    new time/op    delta
UnmarshalVarchar-4     280ns ± 3%      75ns ± 4%  -73.23%  (p=0.000 n=18+19)

name                old alloc/op   new alloc/op   delta
UnmarshalVarchar-4    1.06kB ± 0%    0.03kB ± 0%  -96.97%  (p=0.000 n=20+20)

name                old allocs/op  new allocs/op  delta
UnmarshalVarchar-4      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=20+20)
```
Chris Bannister 7 lat temu
rodzic
commit
f596bd36e1
2 zmienionych plików z 15 dodań i 1 usunięć
  1. 2 1
      marshal.go
  2. 13 0
      marshal_test.go

+ 2 - 1
marshal.go

@@ -232,12 +232,13 @@ func unmarshalVarchar(info TypeInfo, data []byte, value interface{}) error {
 		return nil
 		return nil
 	case *[]byte:
 	case *[]byte:
 		if data != nil {
 		if data != nil {
-			*v = copyBytes(data)
+			*v = append((*v)[:0], data...)
 		} else {
 		} else {
 			*v = nil
 			*v = nil
 		}
 		}
 		return nil
 		return nil
 	}
 	}
+
 	rv := reflect.ValueOf(value)
 	rv := reflect.ValueOf(value)
 	if rv.Kind() != reflect.Ptr {
 	if rv.Kind() != reflect.Ptr {
 		return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
 		return unmarshalErrorf("can not unmarshal into non-pointer %T", value)

+ 13 - 0
marshal_test.go

@@ -1401,3 +1401,16 @@ func TestMarshalDate(t *testing.T) {
 		}
 		}
 	}
 	}
 }
 }
+
+func BenchmarkUnmarshalVarchar(b *testing.B) {
+	b.ReportAllocs()
+	src := make([]byte, 1024)
+	dst := make([]byte, len(src))
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if err := unmarshalVarchar(NativeType{}, src, &dst); err != nil {
+			b.Fatal(err)
+		}
+	}
+}