Quellcode durchsuchen

Lazy-init types & packages

Saves memory & initialization type when name-lookup is not used, by
deferring to first-use.
Justin Santa Barbara vor 7 Jahren
Ursprung
Commit
e4eb82f793
1 geänderte Dateien mit 13 neuen und 3 gelöschten Zeilen
  1. 13 3
      type_map.go

+ 13 - 3
type_map.go

@@ -4,6 +4,7 @@ import (
 	"reflect"
 	"runtime"
 	"strings"
+	"sync"
 	"unsafe"
 )
 
@@ -15,10 +16,17 @@ func typelinks1() [][]unsafe.Pointer
 //go:linkname typelinks2 reflect.typelinks
 func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
 
-var types = map[string]reflect.Type{}
-var packages = map[string]map[string]reflect.Type{}
+// initOnce guards initialization of types and packages
+var initOnce sync.Once
+
+var types map[string]reflect.Type
+var packages map[string]map[string]reflect.Type
+
+// discoverTypes initializes types and packages
+func discoverTypes() {
+	types = make(map[string]reflect.Type)
+	packages = make(map[string]map[string]reflect.Type)
 
-func init() {
 	ver := runtime.Version()
 	if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
 		loadGo15Types()
@@ -90,11 +98,13 @@ type emptyInterface struct {
 
 // TypeByName return the type by its name, just like Class.forName in java
 func TypeByName(typeName string) Type {
+	initOnce.Do(discoverTypes)
 	return Type2(types[typeName])
 }
 
 // TypeByPackageName return the type by its package and name
 func TypeByPackageName(pkgPath string, name string) Type {
+	initOnce.Do(discoverTypes)
 	pkgTypes := packages[pkgPath]
 	if pkgTypes == nil {
 		return nil