Browse Source

codec: optimize getting slice from an array

Ugorji Nwoke 6 years ago
parent
commit
8ee173dc4f
3 changed files with 24 additions and 5 deletions
  1. 1 1
      codec/helper.go
  2. 4 0
      codec/helper_not_unsafe.go
  3. 19 4
      codec/helper_unsafe.go

+ 1 - 1
codec/helper.go

@@ -958,7 +958,7 @@ func (x *BasicHandle) fnLoad(rt reflect.Type, rtid uintptr, checkExt bool) (fn *
 				fi.addrD = false
 				rt2 := reflect.SliceOf(ti.elem)
 				fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
-					d.h.fn(rt2).fd(d, xf, xrv.Slice(0, xrv.Len()))
+					d.h.fn(rt2).fd(d, xf, rvGetSlice4Array(xrv, rt2))
 				}
 				// fn.fd = (*Decoder).kArray
 			case reflect.Struct:

+ 4 - 0
codec/helper_not_unsafe.go

@@ -315,6 +315,10 @@ func rvGetArray4Slice(rv reflect.Value) (v reflect.Value) {
 	return
 }
 
+func rvGetSlice4Array(rv reflect.Value, tslice reflect.Type) (v reflect.Value) {
+	return rv.Slice(0, rv.Len())
+}
+
 func rvCopySlice(dest, src reflect.Value) {
 	reflect.Copy(dest, src)
 }

+ 19 - 4
codec/helper_unsafe.go

@@ -496,7 +496,6 @@ func rvSetDirect(rv reflect.Value, v reflect.Value) {
 	} else {
 		typedmemmove(urv.typ, urv.ptr, uv.ptr)
 	}
-
 }
 
 // rvSlice returns a slice of the slice of lenth
@@ -544,13 +543,29 @@ func rvGetArray4Slice(rv reflect.Value) (v reflect.Value) {
 	return
 }
 
+func rvGetSlice4Array(rv reflect.Value, tslice reflect.Type) (v reflect.Value) {
+	uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
+
+	var x []unsafe.Pointer
+
+	uv.ptr = unsafe.Pointer(&x)
+	uv.typ = ((*unsafeIntf)(unsafe.Pointer(&tslice))).word
+	uv.flag = unsafeFlagIndir | uintptr(reflect.Slice)
+
+	s := (*unsafeSlice)(uv.ptr)
+	s.Data = ((*unsafeReflectValue)(unsafe.Pointer(&rv))).ptr
+	s.Len = rv.Len()
+	s.Cap = s.Len
+	return
+}
+
 func rvCopySlice(dest, src reflect.Value) {
-	var i interface{} = dest.Type().Elem()
-	ui := (*unsafeIntf)(unsafe.Pointer(&i))
+	t := dest.Type().Elem()
 	urv := (*unsafeReflectValue)(unsafe.Pointer(&dest))
 	destPtr := urv.ptr
 	urv = (*unsafeReflectValue)(unsafe.Pointer(&src))
-	typedslicecopy(ui.word, *(*unsafeSlice)(destPtr), *(*unsafeSlice)(urv.ptr))
+	typedslicecopy((*unsafeIntf)(unsafe.Pointer(&t)).word,
+		*(*unsafeSlice)(destPtr), *(*unsafeSlice)(urv.ptr))
 }
 
 // ------------