rft: using reference type to improve performance
diff --git a/decode.go b/decode.go
index 35de60e..25ae24a 100644
--- a/decode.go
+++ b/decode.go
@@ -35,7 +35,7 @@
 	// record type refs, both list and map need it
 	// todo: map
 	typeRefs      *TypeRefs
-	classInfoList []classInfo
+	classInfoList []*classInfo
 	isSkip        bool
 }
 
diff --git a/encode.go b/encode.go
index b0344d1..f20a476 100644
--- a/encode.go
+++ b/encode.go
@@ -33,7 +33,7 @@
 
 // Encoder struct
 type Encoder struct {
-	classInfoList []classInfo
+	classInfoList []*classInfo
 	buffer        []byte
 	refMap        map[unsafe.Pointer]_refElem
 }
diff --git a/java_collection.go b/java_collection.go
index 5e66514..d669d12 100644
--- a/java_collection.go
+++ b/java_collection.go
@@ -88,7 +88,7 @@
 	return nil
 }
 
-func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (JavaCollectionSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
 	//for the java impl of hessian encode collections as list, which will not be decoded as object in go impl, this method should not be called
 	return nil, perrors.New("unexpected collection decode call")
 }
diff --git a/java_sql_time.go b/java_sql_time.go
index a359e8b..51e3abf 100644
--- a/java_sql_time.go
+++ b/java_sql_time.go
@@ -54,7 +54,7 @@
 		i         int
 		idx       int
 		err       error
-		clsDef    classInfo
+		clsDef    *classInfo
 		className string
 		ptrV      reflect.Value
 	)
@@ -116,7 +116,7 @@
 }
 
 // nolint
-func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
 
 	if typ.Kind() != reflect.Struct {
 		return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
diff --git a/java_unknown_exception.go b/java_unknown_exception.go
index 1b4196c..0663c4f 100644
--- a/java_unknown_exception.go
+++ b/java_unknown_exception.go
@@ -28,13 +28,13 @@
 
 var exceptionCheckMutex sync.Mutex
 
-func checkAndGetException(cls classInfo) (structInfo, bool) {
+func checkAndGetException(cls *classInfo) (*structInfo, bool) {
 
 	if len(cls.fieldNameList) < 4 {
-		return structInfo{}, false
+		return nil, false
 	}
 	var (
-		throwable structInfo
+		throwable *structInfo
 		ok        bool
 	)
 	var count = 0
diff --git a/java_unknown_exception_test.go b/java_unknown_exception_test.go
index ea24321..20c8e6c 100644
--- a/java_unknown_exception_test.go
+++ b/java_unknown_exception_test.go
@@ -25,7 +25,7 @@
 )
 
 func TestCheckAndGetException(t *testing.T) {
-	clazzInfo1 := classInfo{
+	clazzInfo1 := &classInfo{
 		javaName:      "com.test.UserDefinedException",
 		fieldNameList: []string{"detailMessage", "code", "suppressedExceptions", "stackTrace", "cause"},
 	}
@@ -35,11 +35,11 @@
 	assert.Equal(t, s.javaName, "com.test.UserDefinedException")
 	assert.Equal(t, s.goName, "hessian.UnknownException")
 
-	clazzInfo2 := classInfo{
+	clazzInfo2 := &classInfo{
 		javaName:      "com.test.UserDefinedException",
 		fieldNameList: []string{"detailMessage", "code", "suppressedExceptions", "cause"},
 	}
 	s, b = checkAndGetException(clazzInfo2)
 	assert.False(t, b)
-	assert.Equal(t, s, structInfo{})
+	assert.Nil(t, s)
 }
diff --git a/list.go b/list.go
index d8ed019..8c70310 100644
--- a/list.go
+++ b/list.go
@@ -114,10 +114,11 @@
 
 	if sliceTy == nil {
 		tpStructInfo, _ := getStructInfo(javaname)
-		tp := tpStructInfo.typ
-		if tp == nil {
+		if tpStructInfo == nil || tpStructInfo.typ == nil {
 			return nil
 		}
+
+		tp := tpStructInfo.typ
 		if tp.Kind() != reflect.Ptr {
 			tp = reflect.New(tp).Type()
 		}
diff --git a/object.go b/object.go
index bec2de4..b398f25 100644
--- a/object.go
+++ b/object.go
@@ -104,7 +104,7 @@
 		idx    int
 		num    int
 		err    error
-		clsDef classInfo
+		clsDef *classInfo
 	)
 
 	vv := reflect.ValueOf(v)
@@ -292,7 +292,7 @@
 		fieldList[i] = fieldName
 	}
 
-	return classInfo{javaName: clsName, fieldNameList: fieldList}, nil
+	return &classInfo{javaName: clsName, fieldNameList: fieldList}, nil
 }
 
 type fieldInfo struct {
@@ -362,7 +362,7 @@
 	return []int{}, nil, perrors.Errorf("failed to find field %s", name)
 }
 
-func (d *Decoder) decInstance(typ reflect.Type, cls classInfo) (interface{}, error) {
+func (d *Decoder) decInstance(typ reflect.Type, cls *classInfo) (interface{}, error) {
 	if typ.Kind() != reflect.Struct {
 		return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
 	}
@@ -537,15 +537,15 @@
 	return vRef.Interface(), nil
 }
 
-func (d *Decoder) appendClsDef(cd classInfo) {
+func (d *Decoder) appendClsDef(cd *classInfo) {
 	d.classInfoList = append(d.classInfoList, cd)
 }
 
-func (d *Decoder) getStructDefByIndex(idx int) (reflect.Type, classInfo, error) {
+func (d *Decoder) getStructDefByIndex(idx int) (reflect.Type, *classInfo, error) {
 	var (
 		ok  bool
-		cls classInfo
-		s   structInfo
+		cls *classInfo
+		s   *structInfo
 		err error
 	)
 
@@ -573,7 +573,7 @@
 		err       error
 		enumName  string
 		ok        bool
-		info      structInfo
+		info      *structInfo
 		enumValue JavaEnum
 	)
 	enumName, err = d.decString(TAG_READ) // java enum class member is "name"
@@ -591,7 +591,7 @@
 }
 
 // skip this object
-func (d *Decoder) skip(cls classInfo) error {
+func (d *Decoder) skip(cls *classInfo) error {
 	len := len(cls.fieldNameList)
 	if len < 1 {
 		return nil
@@ -613,7 +613,7 @@
 		idx int32
 		err error
 		typ reflect.Type
-		cls classInfo
+		cls *classInfo
 	)
 
 	if flag != TAG_READ {
@@ -632,7 +632,7 @@
 		if err != nil {
 			return nil, perrors.Wrap(err, "decObject->decClassDef byte double")
 		}
-		cls, _ = clsDef.(classInfo)
+		cls, _ = clsDef.(*classInfo)
 		//add to slice
 		d.appendClsDef(cls)
 
diff --git a/object_test.go b/object_test.go
index 1bdeafa..7e59157 100644
--- a/object_test.go
+++ b/object_test.go
@@ -564,9 +564,9 @@
 
 func TestSkip(t *testing.T) {
 	// clear pojo
-	pojoRegistry = POJORegistry{
+	pojoRegistry = &POJORegistry{
 		j2g:      make(map[string]string),
-		registry: make(map[string]structInfo),
+		registry: make(map[string]*structInfo),
 	}
 	testDecodeFrameworkWithSkip(t, "replyObject_0", nil)
 	testDecodeFrameworkWithSkip(t, "replyObject_1", nil)
diff --git a/pojo.go b/pojo.go
index 8ed2e42..272037e 100644
--- a/pojo.go
+++ b/pojo.go
@@ -89,15 +89,15 @@
 // POJORegistry pojo registry struct
 type POJORegistry struct {
 	sync.RWMutex
-	classInfoList []classInfo           // {class name, field name list...} list
-	j2g           map[string]string     // java class name --> go struct name
-	registry      map[string]structInfo // go class name --> go struct info
+	classInfoList []*classInfo           // {class name, field name list...} list
+	j2g           map[string]string      // java class name --> go struct name
+	registry      map[string]*structInfo // go class name --> go struct info
 }
 
 var (
-	pojoRegistry = POJORegistry{
+	pojoRegistry = &POJORegistry{
 		j2g:      make(map[string]string),
-		registry: make(map[string]structInfo),
+		registry: make(map[string]*structInfo),
 	}
 	pojoType     = reflect.TypeOf((*POJO)(nil)).Elem()
 	javaEnumType = reflect.TypeOf((*POJOEnum)(nil)).Elem()
@@ -205,8 +205,8 @@
 	clsDef.buffer = append(bHeader, bBody...)
 
 	structInfo.index = len(pojoRegistry.classInfoList)
-	pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, clsDef)
-	pojoRegistry.registry[structInfo.goName] = structInfo
+	pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, &clsDef)
+	pojoRegistry.registry[structInfo.goName] = &structInfo
 
 	return structInfo.index
 }
@@ -307,8 +307,8 @@
 		c = classInfo{javaName: t.javaName, fieldNameList: l}
 		c.buffer = append(c.buffer, b[:]...)
 		t.index = len(pojoRegistry.classInfoList)
-		pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, c)
-		pojoRegistry.registry[t.goName] = t
+		pojoRegistry.classInfoList = append(pojoRegistry.classInfoList, &c)
+		pojoRegistry.registry[t.goName] = &t
 		i = t.index
 	} else {
 		i = -1
@@ -319,23 +319,32 @@
 
 // check if go struct name @goName has been registered or not.
 func checkPOJORegistry(goName string) (int, bool) {
+	s, ok := loadPOJORegistry(goName)
+	if !ok {
+		return -1, false
+	}
+	return s.index, true
+}
+
+// load struct info if go struct name @goName has been registered or not.
+func loadPOJORegistry(goName string) (*structInfo, bool) {
 	var (
 		ok bool
-		s  structInfo
+		s  *structInfo
 	)
 	pojoRegistry.RLock()
 	s, ok = pojoRegistry.registry[goName]
 	pojoRegistry.RUnlock()
 
-	return s.index, ok
+	return s, ok
 }
 
 // @typeName is class's java name
-func getStructInfo(javaName string) (structInfo, bool) {
+func getStructInfo(javaName string) (*structInfo, bool) {
 	var (
 		ok bool
 		g  string
-		s  structInfo
+		s  *structInfo
 	)
 
 	pojoRegistry.RLock()
@@ -348,12 +357,12 @@
 	return s, ok
 }
 
-func getStructDefByIndex(idx int) (reflect.Type, classInfo, error) {
+func getStructDefByIndex(idx int) (reflect.Type, *classInfo, error) {
 	var (
 		ok      bool
 		clsName string
-		cls     classInfo
-		s       structInfo
+		cls     *classInfo
+		s       *structInfo
 	)
 
 	pojoRegistry.RLock()
@@ -380,7 +389,7 @@
 func createInstance(goName string) interface{} {
 	var (
 		ok bool
-		s  structInfo
+		s  *structInfo
 	)
 
 	pojoRegistry.RLock()
diff --git a/serialize.go b/serialize.go
index 2584d10..b57702b 100644
--- a/serialize.go
+++ b/serialize.go
@@ -37,7 +37,7 @@
 
 type Serializer interface {
 	EncObject(*Encoder, POJO) error
-	DecObject(*Decoder, reflect.Type, classInfo) (interface{}, error)
+	DecObject(*Decoder, reflect.Type, *classInfo) (interface{}, error)
 }
 
 var serializerMap = make(map[string]Serializer, 16)
@@ -53,7 +53,7 @@
 
 type IntegerSerializer struct{}
 
-func (IntegerSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (IntegerSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
 	bigInt, err := d.decInstance(typ, cls)
 	if err != nil {
 		return nil, err
@@ -88,7 +88,7 @@
 	return e.encObject(decimal)
 }
 
-func (DecimalSerializer) DecObject(d *Decoder, typ reflect.Type, cls classInfo) (interface{}, error) {
+func (DecimalSerializer) DecObject(d *Decoder, typ reflect.Type, cls *classInfo) (interface{}, error) {
 	dec, err := d.decInstance(typ, cls)
 	if err != nil {
 		return nil, err