Browse Source

codec: remove recognized-rtid logic

Trying to see if a type is a recognized type
(one of the base go types or maps or slices containing them)
so that we can use a fast-path type-switch did not give the
performance we wanted.

We kept it gated behind a const flag (set to false),
but it is time to remove it for good now.
Ugorji Nwoke 8 years ago
parent
commit
792f4ab7b3
7 changed files with 45 additions and 279 deletions
  1. 32 103
      codec/decode.go
  2. 11 47
      codec/encode.go
  3. 0 7
      codec/fast-path.generated.go
  4. 0 7
      codec/fast-path.go.tmpl
  5. 1 1
      codec/gen-helper.generated.go
  6. 1 1
      codec/gen-helper.go.tmpl
  7. 0 113
      codec/helper.go

+ 32 - 103
codec/decode.go

@@ -974,13 +974,13 @@ func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
 				rvn = reflect.ValueOf(&v2).Elem()
 				rvn = reflect.ValueOf(&v2).Elem()
 			}
 			}
 		} else {
 		} else {
-			rvn = reflect.New(d.h.MapType)
-			if useLookupRecognizedTypes && d.mtr { // isRecognizedRtid(d.mtid) {
+			if d.mtr {
+				rvn = reflect.New(d.h.MapType)
 				d.decode(rv2i(rvn))
 				d.decode(rv2i(rvn))
 				rvn = rvn.Elem()
 				rvn = rvn.Elem()
 			} else {
 			} else {
-				rvn = rvn.Elem()
-				d.decodeValue(rvn, nil, false, true)
+				rvn = reflect.New(d.h.MapType).Elem()
+				d.decodeValue(rvn, nil, true)
 			}
 			}
 		}
 		}
 	case valueTypeArray:
 	case valueTypeArray:
@@ -1002,13 +1002,13 @@ func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
 				rvn = rvn2
 				rvn = rvn2
 			}
 			}
 		} else {
 		} else {
-			rvn = reflect.New(d.h.SliceType)
-			if useLookupRecognizedTypes && d.str { // isRecognizedRtid(d.stid) {
+			if d.str {
+				rvn = reflect.New(d.h.SliceType)
 				d.decode(rv2i(rvn))
 				d.decode(rv2i(rvn))
 				rvn = rvn.Elem()
 				rvn = rvn.Elem()
 			} else {
 			} else {
-				rvn = rvn.Elem()
-				d.decodeValue(rvn, nil, false, true)
+				rvn = reflect.New(d.h.SliceType).Elem()
+				d.decodeValue(rvn, nil, true)
 			}
 			}
 		}
 		}
 	case valueTypeExt:
 	case valueTypeExt:
@@ -1104,25 +1104,17 @@ func (d *Decoder) kInterface(f *codecFnInfo, rv reflect.Value) {
 
 
 	rvn2, canDecode := isDecodeable(rvn)
 	rvn2, canDecode := isDecodeable(rvn)
 	if canDecode {
 	if canDecode {
-		d.decodeValue(rvn2, nil, true, true)
+		d.decodeValue(rvn2, nil, true)
 		return
 		return
 	}
 	}
 
 
 	rvn2 = reflect.New(rvn.Type()).Elem()
 	rvn2 = reflect.New(rvn.Type()).Elem()
 	rvn2.Set(rvn)
 	rvn2.Set(rvn)
-	d.decodeValue(rvn2, nil, true, true)
+	d.decodeValue(rvn2, nil, true)
 	rv.Set(rvn2)
 	rv.Set(rvn2)
 }
 }
 
 
 func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
-	// checking if recognized within kstruct is too expensive.
-	// only check where you can determine if valid outside the loop
-	// ie on homogenous collections: slices, arrays and maps.
-	//
-	// if true, we don't create too many decFn's.
-	// It's a delicate balance.
-	const checkRecognized bool = false // false: TODO
-
 	fti := f.ti
 	fti := f.ti
 	dd := d.d
 	dd := d.d
 	elemsep := d.hh.hasElemSeparators()
 	elemsep := d.hh.hasElemSeparators()
@@ -1153,7 +1145,7 @@ func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 				if dd.TryDecodeAsNil() {
 				if dd.TryDecodeAsNil() {
 					si.setToZeroValue(rv)
 					si.setToZeroValue(rv)
 				} else {
 				} else {
-					d.decodeValue(sfn.field(si), nil, checkRecognized, true)
+					d.decodeValue(sfn.field(si), nil, true)
 				}
 				}
 			} else {
 			} else {
 				d.structFieldNotFound(-1, rvkencname)
 				d.structFieldNotFound(-1, rvkencname)
@@ -1180,7 +1172,7 @@ func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
 			if dd.TryDecodeAsNil() {
 			if dd.TryDecodeAsNil() {
 				si.setToZeroValue(rv)
 				si.setToZeroValue(rv)
 			} else {
 			} else {
-				d.decodeValue(sfn.field(si), nil, checkRecognized, true)
+				d.decodeValue(sfn.field(si), nil, true)
 			}
 			}
 		}
 		}
 		if containerLen > len(fti.sfip) {
 		if containerLen > len(fti.sfip) {
@@ -1256,7 +1248,6 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 
 
 	rtelem0Size := int(rtelem0.Size())
 	rtelem0Size := int(rtelem0.Size())
 	rtElem0Kind := rtelem0.Kind()
 	rtElem0Kind := rtelem0.Kind()
-	rtElem0Id := rt2id(rtelem0)
 	rtelem0Mut := !isImmutableKind(rtElem0Kind)
 	rtelem0Mut := !isImmutableKind(rtElem0Kind)
 	rtelem := rtelem0
 	rtelem := rtelem0
 	rtelemkind := rtelem.Kind()
 	rtelemkind := rtelem.Kind()
@@ -1304,12 +1295,6 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 		}
 		}
 	}
 	}
 
 
-	var recognizedRtid, recognizedRtidPtr bool
-	if useLookupRecognizedTypes {
-		recognizedRtid = isRecognizedRtid(rtElem0Id)
-		recognizedRtidPtr = isRecognizedRtidPtr(rtElem0Id)
-	}
-
 	// consider creating new element once, and just decoding into it.
 	// consider creating new element once, and just decoding into it.
 	var rtelem0Zero reflect.Value
 	var rtelem0Zero reflect.Value
 	var rtelem0ZeroValid bool
 	var rtelem0ZeroValid bool
@@ -1339,14 +1324,10 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
 			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
 				rv9 = reflect.New(rtelem0).Elem()
 				rv9 = reflect.New(rtelem0).Elem()
 			}
 			}
-			if useLookupRecognizedTypes && (recognizedRtid || recognizedRtidPtr) {
-				d.decode(rv2i(rv9.Addr()))
-			} else {
-				if fn == nil {
-					fn = d.cf.get(rtelem, true, true)
-				}
-				d.decodeValue(rv9, fn, false, true)
+			if fn == nil {
+				fn = d.cf.get(rtelem, true, true)
 			}
 			}
+			d.decodeValue(rv9, fn, true)
 			rv.Send(rv9)
 			rv.Send(rv9)
 		} else {
 		} else {
 			// if indefinite, etc, then expand the slice if necessary
 			// if indefinite, etc, then expand the slice if necessary
@@ -1383,19 +1364,10 @@ func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 					continue
 					continue
 				}
 				}
 
 
-				if useLookupRecognizedTypes && recognizedRtid {
-					d.decode(rv2i(rv9.Addr()))
-				} else if useLookupRecognizedTypes && recognizedRtidPtr { // && !rv9.IsNil() {
-					if rv9.IsNil() {
-						rv9.Set(reflect.New(rtelem))
-					}
-					d.decode(rv2i(rv9))
-				} else {
-					if fn == nil {
-						fn = d.cf.get(rtelem, true, true)
-					}
-					d.decodeValue(rv9, fn, false, true)
+				if fn == nil {
+					fn = d.cf.get(rtelem, true, true)
 				}
 				}
+				d.decodeValue(rv9, fn, true)
 			}
 			}
 		}
 		}
 	}
 	}
@@ -1441,15 +1413,7 @@ func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
 
 
 	ktype, vtype := ti.rt.Key(), ti.rt.Elem()
 	ktype, vtype := ti.rt.Key(), ti.rt.Elem()
 	ktypeId := rt2id(ktype)
 	ktypeId := rt2id(ktype)
-	vtypeId := rt2id(vtype)
 	vtypeKind := vtype.Kind()
 	vtypeKind := vtype.Kind()
-	var recognizedKtyp, recognizedVtyp, recognizedPtrKtyp, recognizedPtrVtyp bool
-	if useLookupRecognizedTypes {
-		recognizedKtyp = isRecognizedRtid(ktypeId)
-		recognizedVtyp = isRecognizedRtid(vtypeId)
-		recognizedPtrKtyp = isRecognizedRtidPtr(ktypeId)
-		recognizedPtrVtyp = isRecognizedRtidPtr(vtypeId)
-	}
 
 
 	var keyFn, valFn *codecFn
 	var keyFn, valFn *codecFn
 	var ktypeLo, vtypeLo reflect.Type
 	var ktypeLo, vtypeLo reflect.Type
@@ -1501,19 +1465,11 @@ func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
 			kstrbs = dd.DecodeStringAsBytes()
 			kstrbs = dd.DecodeStringAsBytes()
 			rvk.SetString(stringView(kstrbs))
 			rvk.SetString(stringView(kstrbs))
 			// NOTE: if doing an insert, you MUST use a real string (not stringview)
 			// NOTE: if doing an insert, you MUST use a real string (not stringview)
-		} else if useLookupRecognizedTypes && recognizedKtyp {
-			d.decode(rv2i(rvkp))
-			// rvk = rvkp.Elem() //TODO: remove, unnecessary
-		} else if useLookupRecognizedTypes && recognizedPtrKtyp {
-			if rvk.IsNil() {
-				rvk = reflect.New(ktypeLo)
-			}
-			d.decode(rv2i(rvk))
 		} else {
 		} else {
 			if keyFn == nil {
 			if keyFn == nil {
 				keyFn = d.cf.get(ktypeLo, true, true)
 				keyFn = d.cf.get(ktypeLo, true, true)
 			}
 			}
-			d.decodeValue(rvk, keyFn, false, true)
+			d.decodeValue(rvk, keyFn, true)
 		}
 		}
 		// special case if a byte array.
 		// special case if a byte array.
 		if ktypeIsIntf {
 		if ktypeIsIntf {
@@ -1580,21 +1536,11 @@ func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
 		if mapSet && ktypeIsString {
 		if mapSet && ktypeIsString {
 			rvk.SetString(d.string(kstrbs))
 			rvk.SetString(d.string(kstrbs))
 		}
 		}
-		if useLookupRecognizedTypes && recognizedVtyp && rvv.CanAddr() {
-			d.decode(rv2i(rvv.Addr()))
-		} else if useLookupRecognizedTypes && recognizedPtrVtyp {
-			if rvv.IsNil() {
-				rvv = reflect.New(vtypeLo)
-				mapSet = true
-			}
-			d.decode(rv2i(rvv))
-		} else {
-			if valFn == nil {
-				valFn = d.cf.get(vtypeLo, true, true)
-			}
-			d.decodeValue(rvv, valFn, false, true)
-			// d.decodeValueFn(rvv, valFn)
+		if valFn == nil {
+			valFn = d.cf.get(vtypeLo, true, true)
 		}
 		}
+		d.decodeValue(rvv, valFn, true)
+		// d.decodeValueFn(rvv, valFn)
 		if mapSet {
 		if mapSet {
 			rv.SetMapIndex(rvk, rvv)
 			rv.SetMapIndex(rvk, rvv)
 		}
 		}
@@ -1720,7 +1666,7 @@ type Decoder struct {
 	hh Handle
 	hh Handle
 	h  *BasicHandle
 	h  *BasicHandle
 
 
-	mtr, mtrp, str, strp bool //
+	mtr, str bool // whether maptype or slicetype are known types
 
 
 	be    bool // is binary encoding
 	be    bool // is binary encoding
 	bytes bool // is bytes reader
 	bytes bool // is bytes reader
@@ -1813,23 +1759,16 @@ func (d *Decoder) resetCommon() {
 	d.d.reset()
 	d.d.reset()
 	d.cf.reset(d.hh)
 	d.cf.reset(d.hh)
 	d.err = nil
 	d.err = nil
-	// reset all things which were cached from the Handle,
-	// but could be changed.
+	// reset all things which were cached from the Handle, but could change
 	d.mtid, d.stid = 0, 0
 	d.mtid, d.stid = 0, 0
-	d.mtr, d.mtrp, d.str, d.strp = false, false, false, false
+	d.mtr, d.str = false, false
 	if d.h.MapType != nil {
 	if d.h.MapType != nil {
 		d.mtid = rt2id(d.h.MapType)
 		d.mtid = rt2id(d.h.MapType)
-		if useLookupRecognizedTypes {
-			d.mtr = isRecognizedRtid(d.mtid)
-			d.mtrp = isRecognizedRtidPtr(d.mtid)
-		}
+		d.mtr = fastpathAV.index(d.mtid) != -1
 	}
 	}
 	if d.h.SliceType != nil {
 	if d.h.SliceType != nil {
 		d.stid = rt2id(d.h.SliceType)
 		d.stid = rt2id(d.h.SliceType)
-		if useLookupRecognizedTypes {
-			d.str = isRecognizedRtid(d.stid)
-			d.strp = isRecognizedRtidPtr(d.stid)
-		}
+		d.str = fastpathAV.index(d.stid) != -1
 	}
 	}
 }
 }
 
 
@@ -2066,7 +2005,7 @@ func (d *Decoder) decode(iv interface{}) {
 
 
 	case reflect.Value:
 	case reflect.Value:
 		v = d.ensureDecodeable(v)
 		v = d.ensureDecodeable(v)
-		d.decodeValue(v, nil, false, true) // TODO: maybe ask to recognize ...
+		d.decodeValue(v, nil, true) // TODO: maybe ask to recognize ...
 
 
 	case *string:
 	case *string:
 		*v = d.d.DecodeString()
 		*v = d.d.DecodeString()
@@ -2103,20 +2042,20 @@ func (d *Decoder) decode(iv interface{}) {
 		*v = d.rawBytes()
 		*v = d.rawBytes()
 
 
 	case *interface{}:
 	case *interface{}:
-		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, false, true) // TODO: consider recognize here
+		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, true) // TODO: consider recognize here
 		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
 		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
 
 
 	default:
 	default:
 		if !fastpathDecodeTypeSwitch(iv, d) {
 		if !fastpathDecodeTypeSwitch(iv, d) {
 			v := reflect.ValueOf(iv)
 			v := reflect.ValueOf(iv)
 			v = d.ensureDecodeable(v)
 			v = d.ensureDecodeable(v)
-			d.decodeValue(v, nil, false, false)
+			d.decodeValue(v, nil, false)
 			// d.decodeValueFallback(v)
 			// d.decodeValueFallback(v)
 		}
 		}
 	}
 	}
 }
 }
 
 
-func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, tryRecognized, chkAll bool) {
+func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, chkAll bool) {
 	// If stream is not containing a nil value, then we can deref to the base
 	// If stream is not containing a nil value, then we can deref to the base
 	// non-pointer value, and decode into that.
 	// non-pointer value, and decode into that.
 	var rvp reflect.Value
 	var rvp reflect.Value
@@ -2135,16 +2074,6 @@ func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, tryRecognized, chkA
 		}
 		}
 	}
 	}
 
 
-	if useLookupRecognizedTypes && tryRecognized && isRecognizedRtid(rv2rtid(rv)) {
-		if rvpValid {
-			d.decode(rv2i(rvp))
-			return
-		} else if rv.CanAddr() {
-			d.decode(rv2i(rv.Addr()))
-			return
-		}
-	}
-
 	if fn == nil {
 	if fn == nil {
 		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
 		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
 		fn = d.cf.get(rv.Type(), chkAll, true) // chkAll, chkAll)
 		fn = d.cf.get(rv.Type(), chkAll, true) // chkAll, chkAll)

+ 11 - 47
codec/encode.go

@@ -484,20 +484,14 @@ func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 
 
 	if l > 0 {
 	if l > 0 {
 		var fn *codecFn
 		var fn *codecFn
-		var recognizedVtyp bool
-		if useLookupRecognizedTypes {
-			recognizedVtyp = isRecognizedRtidOrPtr(rt2id(rtelem))
+		for rtelem.Kind() == reflect.Ptr {
+			rtelem = rtelem.Elem()
 		}
 		}
-		if !(useLookupRecognizedTypes && recognizedVtyp) {
-			for rtelem.Kind() == reflect.Ptr {
-				rtelem = rtelem.Elem()
-			}
-			// if kind is reflect.Interface, do not pre-determine the
-			// encoding type, because preEncodeValue may break it down to
-			// a concrete type and kInterface will bomb.
-			if rtelem.Kind() != reflect.Interface {
-				fn = e.cf.get(rtelem, true, true)
-			}
+		// if kind is reflect.Interface, do not pre-determine the
+		// encoding type, because preEncodeValue may break it down to
+		// a concrete type and kInterface will bomb.
+		if rtelem.Kind() != reflect.Interface {
+			fn = e.cf.get(rtelem, true, true)
 		}
 		}
 		// TODO: Consider perf implication of encoding odd index values as symbols if type is string
 		// TODO: Consider perf implication of encoding odd index values as symbols if type is string
 		for j := 0; j < l; j++ {
 		for j := 0; j < l; j++ {
@@ -514,20 +508,12 @@ func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
 			}
 			}
 			if f.seq == seqTypeChan {
 			if f.seq == seqTypeChan {
 				if rv2, ok2 := rv.Recv(); ok2 {
 				if rv2, ok2 := rv.Recv(); ok2 {
-					if useLookupRecognizedTypes && recognizedVtyp {
-						e.encode(rv2i(rv2))
-					} else {
-						e.encodeValue(rv2, fn, true)
-					}
+					e.encodeValue(rv2, fn, true)
 				} else {
 				} else {
 					ee.EncodeNil() // WE HAVE TO DO SOMETHING, so nil if nothing received.
 					ee.EncodeNil() // WE HAVE TO DO SOMETHING, so nil if nothing received.
 				}
 				}
 			} else {
 			} else {
-				if useLookupRecognizedTypes && recognizedVtyp {
-					e.encode(rv2i(rv.Index(j)))
-				} else {
-					e.encodeValue(rv.Index(j), fn, true)
-				}
+				e.encodeValue(rv.Index(j), fn, true)
 			}
 			}
 		}
 		}
 	}
 	}
@@ -744,7 +730,6 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 	rtval0 := ti.rt.Elem()
 	rtval0 := ti.rt.Elem()
 	rtval := rtval0
 	rtval := rtval0
 	rtkeyid := rt2id(rtkey0)
 	rtkeyid := rt2id(rtkey0)
-	rtvalid := rt2id(rtval0)
 	for rtval.Kind() == reflect.Ptr {
 	for rtval.Kind() == reflect.Ptr {
 		rtval = rtval.Elem()
 		rtval = rtval.Elem()
 	}
 	}
@@ -759,17 +744,10 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 		return
 		return
 	}
 	}
 
 
-	var recognizedKtyp, recognizedVtyp bool
 	var keyTypeIsString = rtkeyid == stringTypId
 	var keyTypeIsString = rtkeyid == stringTypId
 	if keyTypeIsString {
 	if keyTypeIsString {
 		asSymbols = e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 		asSymbols = e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
 	} else {
 	} else {
-		if useLookupRecognizedTypes {
-			recognizedKtyp = isRecognizedRtidOrPtr(rtkeyid)
-			if recognizedKtyp {
-				goto LABEL1
-			}
-		}
 		for rtkey.Kind() == reflect.Ptr {
 		for rtkey.Kind() == reflect.Ptr {
 			rtkey = rtkey.Elem()
 			rtkey = rtkey.Elem()
 		}
 		}
@@ -780,10 +758,6 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 	}
 	}
 
 
 	// for j, lmks := 0, len(mks); j < lmks; j++ {
 	// for j, lmks := 0, len(mks); j < lmks; j++ {
-LABEL1:
-	if useLookupRecognizedTypes {
-		recognizedVtyp = isRecognizedRtidOrPtr(rtvalid)
-	}
 	for j := range mks {
 	for j := range mks {
 		if elemsep {
 		if elemsep {
 			ee.WriteMapElemKey()
 			ee.WriteMapElemKey()
@@ -794,19 +768,14 @@ LABEL1:
 			} else {
 			} else {
 				ee.EncodeString(c_UTF8, mks[j].String())
 				ee.EncodeString(c_UTF8, mks[j].String())
 			}
 			}
-		} else if useLookupRecognizedTypes && recognizedKtyp {
-			e.encode(rv2i(mks[j]))
 		} else {
 		} else {
 			e.encodeValue(mks[j], keyFn, true)
 			e.encodeValue(mks[j], keyFn, true)
 		}
 		}
 		if elemsep {
 		if elemsep {
 			ee.WriteMapElemValue()
 			ee.WriteMapElemValue()
 		}
 		}
-		if useLookupRecognizedTypes && recognizedVtyp {
-			e.encode(rv2i(rv.MapIndex(mks[j])))
-		} else {
-			e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
-		}
+		e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
+
 	}
 	}
 	ee.WriteMapEnd()
 	ee.WriteMapEnd()
 }
 }
@@ -1297,11 +1266,6 @@ TOP:
 
 
 	if fn == nil {
 	if fn == nil {
 		rt := rv.Type()
 		rt := rv.Type()
-		// TODO: calling isRecognizedRtid here is a major slowdown
-		if false && useLookupRecognizedTypes && isRecognizedRtidOrPtr(rt2id(rt)) {
-			e.encode(rv2i(rv))
-			return
-		}
 		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
 		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
 		fn = e.cf.get(rt, checkFastpath, true)
 		fn = e.cf.get(rt, checkFastpath, true)
 	}
 	}

+ 0 - 7
codec/fast-path.generated.go

@@ -80,19 +80,12 @@ var fastpathAV fastpathA
 
 
 // due to possible initialization loop error, make fastpath in an init()
 // due to possible initialization loop error, make fastpath in an init()
 func init() {
 func init() {
-	if useLookupRecognizedTypes && recognizedRtidsLoaded {
-		panic("recognizedRtidsLoaded = true - cannot happen")
-	}
 	i := 0
 	i := 0
 	fn := func(v interface{},
 	fn := func(v interface{},
 		fe func(*Encoder, *codecFnInfo, reflect.Value),
 		fe func(*Encoder, *codecFnInfo, reflect.Value),
 		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
 		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
 		xrt := reflect.TypeOf(v)
 		xrt := reflect.TypeOf(v)
 		xptr := rt2id(xrt)
 		xptr := rt2id(xrt)
-		if useLookupRecognizedTypes {
-			recognizedRtids = append(recognizedRtids, xptr)
-			recognizedRtidPtrs = append(recognizedRtidPtrs, rt2id(reflect.PtrTo(xrt)))
-		}
 		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
 		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
 		i++
 		i++
 		return
 		return

+ 0 - 7
codec/fast-path.go.tmpl

@@ -80,19 +80,12 @@ var fastpathAV fastpathA
 
 
 // due to possible initialization loop error, make fastpath in an init()
 // due to possible initialization loop error, make fastpath in an init()
 func init() {
 func init() {
-	if useLookupRecognizedTypes && recognizedRtidsLoaded {
-		panic("recognizedRtidsLoaded = true - cannot happen")
-	}
 	i := 0
 	i := 0
 	fn := func(v interface{},
 	fn := func(v interface{},
 		fe func(*Encoder, *codecFnInfo, reflect.Value),
 		fe func(*Encoder, *codecFnInfo, reflect.Value),
 		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
 		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
 		xrt := reflect.TypeOf(v)
 		xrt := reflect.TypeOf(v)
 		xptr := rt2id(xrt)
 		xptr := rt2id(xrt)
-		if useLookupRecognizedTypes {
-			recognizedRtids = append(recognizedRtids, xptr)
-			recognizedRtidPtrs = append(recognizedRtidPtrs, rt2id(reflect.PtrTo(xrt)))
-		}
 		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
 		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
 		i++
 		i++
 		return
 		return

+ 1 - 1
codec/gen-helper.generated.go

@@ -155,7 +155,7 @@ func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
 	if chkPtr {
 	if chkPtr {
 		rv = f.d.ensureDecodeable(rv)
 		rv = f.d.ensureDecodeable(rv)
 	}
 	}
-	f.d.decodeValue(rv, nil, false, false)
+	f.d.decodeValue(rv, nil, false)
 	// f.d.decodeValueFallback(rv)
 	// f.d.decodeValueFallback(rv)
 }
 }
 
 

+ 1 - 1
codec/gen-helper.go.tmpl

@@ -142,7 +142,7 @@ func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
 	if chkPtr {
 	if chkPtr {
 		rv = f.d.ensureDecodeable(rv)
 		rv = f.d.ensureDecodeable(rv)
 	}
 	}
-	f.d.decodeValue(rv, nil, false, false)
+	f.d.decodeValue(rv, nil, false)
 	// f.d.decodeValueFallback(rv)
 	// f.d.decodeValueFallback(rv)
 }
 }
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
 // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*

+ 0 - 113
codec/helper.go

@@ -128,40 +128,6 @@ const (
 	// allowing zero-alloc initialization.
 	// allowing zero-alloc initialization.
 	arrayCacheLen = 8
 	arrayCacheLen = 8
 
 
-	// We tried an optimization, where we detect if a type is one of the known types
-	// we optimized for (e.g. int, []uint64, etc).
-	//
-	// However, we notice some worse performance when using this optimization.
-	// So we hide it behind a flag, to turn on if needed.
-	useLookupRecognizedTypes = false
-
-	// using recognized allows us to do d.decode(interface{}) instead of d.decodeValue(reflect.Value)
-	// when we can infer that the kind of the interface{} is one of the ones hard-coded in the
-	// type switch for known types or the ones defined by fast-path.
-	//
-	// However, it seems we get better performance when we don't recognize, and just let
-	// reflection handle it.
-	//
-	// Reasoning is as below:
-	// typeswitch is a binary search with a branch to a code-point.
-	// getdecfn is a binary search with a call to a function pointer.
-	//
-	// both are about the same.
-	//
-	// so: why prefer typeswitch?
-	//
-	// is recognized does the following:
-	// - lookup rtid
-	// - check if in sorted list
-	// - calls decode(type switch)
-	//   - 1 or 2 binary search to a point in code
-	//   - branch there
-	//
-	// vs getdecfn
-	// - lookup rtid
-	// - check in sorted list for a function pointer
-	// - calls it to decode using reflection (optimized)
-
 	// always set xDebug = false before releasing software
 	// always set xDebug = false before releasing software
 	xDebug = true
 	xDebug = true
 )
 )
@@ -408,85 +374,6 @@ var immutableKindsSet = [32]bool{
 	// reflect.UnsafePointer
 	// reflect.UnsafePointer
 }
 }
 
 
-var (
-	recognizedRtids       []uintptr
-	recognizedRtidPtrs    []uintptr
-	recognizedRtidOrPtrs  []uintptr
-	recognizedRtidsLoaded bool
-)
-
-func init() {
-	if !useLookupRecognizedTypes {
-		return
-	}
-	if recognizedRtidsLoaded {
-		panic("recognizedRtidsLoaded = true - cannot happen")
-	}
-	for _, v := range [...]interface{}{
-		float32(0),
-		float64(0),
-		uintptr(0),
-		uint(0),
-		uint8(0),
-		uint16(0),
-		uint32(0),
-		uint64(0),
-		uintptr(0),
-		int(0),
-		int8(0),
-		int16(0),
-		int32(0),
-		int64(0),
-		bool(false),
-		string(""),
-		Raw{},
-		[]byte(nil),
-	} {
-		rt := reflect.TypeOf(v)
-		recognizedRtids = append(recognizedRtids, rt2id(rt))
-		recognizedRtidPtrs = append(recognizedRtidPtrs, rt2id(reflect.PtrTo(rt)))
-	}
-
-	// now sort it.
-	sort.Sort(uintptrSlice(recognizedRtids))
-	sort.Sort(uintptrSlice(recognizedRtidPtrs))
-	recognizedRtidOrPtrs = make([]uintptr, len(recognizedRtids)+len(recognizedRtidPtrs))
-	copy(recognizedRtidOrPtrs, recognizedRtids)
-	copy(recognizedRtidOrPtrs[len(recognizedRtids):], recognizedRtidPtrs)
-	sort.Sort(uintptrSlice(recognizedRtidOrPtrs))
-
-	recognizedRtidsLoaded = true
-}
-
-func containsU(s []uintptr, v uintptr) bool {
-	// return false // TODO: REMOVE
-	h, i, j := 0, 0, len(s)
-	for i < j {
-		h = i + (j-i)/2
-		if s[h] < v {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	if i < len(s) && s[i] == v {
-		return true
-	}
-	return false
-}
-
-func isRecognizedRtid(rtid uintptr) bool {
-	return containsU(recognizedRtids, rtid)
-}
-
-func isRecognizedRtidPtr(rtid uintptr) bool {
-	return containsU(recognizedRtidPtrs, rtid)
-}
-
-func isRecognizedRtidOrPtr(rtid uintptr) bool {
-	return containsU(recognizedRtidOrPtrs, rtid)
-}
-
 // Selfer defines methods by which a value can encode or decode itself.
 // Selfer defines methods by which a value can encode or decode itself.
 //
 //
 // Any type which implements Selfer will be able to encode or decode itself.
 // Any type which implements Selfer will be able to encode or decode itself.