mirror of
https://github.com/golang/go
synced 2024-11-23 11:00:08 -07:00
encoding/gob: avoid a pointer to wireType in typeInfo
wireType itself is just a struct with seven pointer fields, so an indirection doesn't feel necessary to noticeably reduce the amount of memory that typeInfo takes for each Go type registered in gob. The indirection does add a small amount of overhead though, particularly one extra allocation when registering a type, which is done a number of times as part of init. For consistency, also update wireTypeUserInfo to not use a pointer. Measuring via one of the end-to-end benchmarks and benchinit: goos: linux goarch: amd64 pkg: encoding/gob cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics │ old │ new │ │ sec/op │ sec/op vs base │ EndToEndPipe-16 736.8n ± 5% 733.9n ± 5% ~ (p=0.971 n=10) EncodingGob 177.6µ ± 0% 173.6µ ± 0% -2.27% (p=0.000 n=10) geomean 11.44µ 11.29µ -1.34% │ old │ new │ │ B/op │ B/op vs base │ EndToEndPipe-16 1.766Ki ± 0% 1.766Ki ± 0% ~ (p=1.000 n=10) ¹ EncodingGob 38.47Ki ± 0% 38.27Ki ± 0% -0.50% (p=0.000 n=10) geomean 8.241Ki 8.220Ki -0.25% ¹ all samples are equal │ old │ new │ │ allocs/op │ allocs/op vs base │ EndToEndPipe-16 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ EncodingGob 652.0 ± 0% 642.0 ± 0% -1.53% (p=0.000 n=10) geomean 36.11 35.83 -0.77% ¹ all samples are equal Change-Id: I528080b7d990ed595683f155a1ae25dcd26394b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/479398 Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Rob Pike <r@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
6a51c000de
commit
4d296bcbc2
@ -263,7 +263,7 @@ var (
|
||||
|
||||
// Predefined because it's needed by the Decoder
|
||||
var tWireType = mustGetTypeInfo(reflect.TypeOf((*wireType)(nil)).Elem()).id
|
||||
var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
|
||||
var wireTypeUserInfo *userTypeInfo // userTypeInfo of wireType
|
||||
|
||||
func init() {
|
||||
// Some magic numbers to make sure there are no surprises.
|
||||
@ -284,7 +284,7 @@ func init() {
|
||||
}
|
||||
idToType = idToType[:firstUserId]
|
||||
registerBasics()
|
||||
wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
|
||||
wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)).Elem())
|
||||
}
|
||||
|
||||
// Array type
|
||||
@ -675,7 +675,7 @@ type typeInfo struct {
|
||||
id typeId
|
||||
encInit sync.Mutex // protects creation of encoder
|
||||
encoder atomic.Pointer[encEngine]
|
||||
wire *wireType
|
||||
wire wireType
|
||||
}
|
||||
|
||||
// typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo.
|
||||
@ -736,27 +736,27 @@ func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
|
||||
gt := userType.id().gobType().(*gobEncoderType)
|
||||
switch ut.externalEnc {
|
||||
case xGob:
|
||||
info.wire = &wireType{GobEncoderT: gt}
|
||||
info.wire.GobEncoderT = gt
|
||||
case xBinary:
|
||||
info.wire = &wireType{BinaryMarshalerT: gt}
|
||||
info.wire.BinaryMarshalerT = gt
|
||||
case xText:
|
||||
info.wire = &wireType{TextMarshalerT: gt}
|
||||
info.wire.TextMarshalerT = gt
|
||||
}
|
||||
rt = ut.user
|
||||
} else {
|
||||
t := info.id.gobType()
|
||||
switch typ := rt; typ.Kind() {
|
||||
case reflect.Array:
|
||||
info.wire = &wireType{ArrayT: t.(*arrayType)}
|
||||
info.wire.ArrayT = t.(*arrayType)
|
||||
case reflect.Map:
|
||||
info.wire = &wireType{MapT: t.(*mapType)}
|
||||
info.wire.MapT = t.(*mapType)
|
||||
case reflect.Slice:
|
||||
// []byte == []uint8 is a special case handled separately
|
||||
if typ.Elem().Kind() != reflect.Uint8 {
|
||||
info.wire = &wireType{SliceT: t.(*sliceType)}
|
||||
info.wire.SliceT = t.(*sliceType)
|
||||
}
|
||||
case reflect.Struct:
|
||||
info.wire = &wireType{StructT: t.(*structType)}
|
||||
info.wire.StructT = t.(*structType)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user