vdl: Add generated vars for TypeOf, for better performance.
Also changed vdl.Decoder.StartValue to take a *vdl.Type argument,
and perform the compatibility check. This gives up to an
additional 10% improvement, and makes it easier to optimize the
compatibility check in the future, since it's now only performed
by the 3 decoders (vom, vdl.Value and vdl.pipe).
Some numbers. In general all the generated stuff gets better:
old ns/op new ns/op delta
RpcRequestZeroSingleShotEncode 51010 41028 -19.57%
RpcRequestZeroRepeatedEncode 302 194 -35.76%
RpcRequestZeroSingleShotDecode 1962 1636 -16.62%
RpcRequestZeroRepeatedDecode 484 281 -41.94%
RpcRequestFullSingleShotEncode 63755 47481 -25.53%
RpcRequestFullRepeatedEncode 9407 5558 -40.92%
RpcRequestFullSingleShotDecode 58886 58863 -0.04%
RpcRequestFullRepeatedDecode 55303 54106 -2.16%
RpcResponseZeroSingleShotEncode 51700 40604 -21.46%
RpcResponseZeroRepeatedEncode 635 514 -19.06%
RpcResponseZeroSingleShotDecode 2026 1755 -13.38%
RpcResponseZeroRepeatedDecode 524 304 -41.98%
RpcResponseFullSingleShotEncode 106038 91816 -13.41%
RpcResponseFullRepeatedEncode 44273 42005 -5.12%
RpcResponseFullSingleShotDecode 43271 42635 -1.47%
RpcResponseFullRepeatedDecode 38608 37251 -3.51%
For some reason, the reflect version of large-list single-shot
encoding gets much worse. I'm not sure why. But I'm going to
ignore that for now, since I think there's plenty of other
optimizations we can explore.
old ns/op new ns/op delta
LargeListSingleShotEncodeReflect 19279360 21696617 +12.54%
LargeListRepeatedEncodeReflect 19055693 19550742 +2.60%
LargeListSingleShotDecodeReflect 34161615 32556162 -4.70%
LargeListRepeatedDecodeReflect 33647837 31846309 -5.35%
LargeListSingleShotEncode 3951128 3984021 +0.83%
LargeListRepeatedEncode 3870694 3895734 +0.65%
LargeListSingleShotDecode 5221050 5465362 +4.68%
LargeListRepeatedDecode 5211915 5246888 +0.67%
MultiPart: 2/5
Change-Id: I6ab4638b98cd4f54ce526064859b3b60d9db419a
diff --git a/test/fortune/fortune.vdl.go b/test/fortune/fortune.vdl.go
index a414e83..f629eba 100644
--- a/test/fortune/fortune.vdl.go
+++ b/test/fortune/fortune.vdl.go
@@ -8,7 +8,6 @@
package fortune
import (
- "fmt"
"io"
"v.io/v23"
"v.io/v23/context"
@@ -49,7 +48,7 @@
}
func (x ComplexErrorParam) VDLWrite(enc vdl.Encoder) error {
- if err := enc.StartValue(vdl.TypeOf((*ComplexErrorParam)(nil)).Elem()); err != nil {
+ if err := enc.StartValue(__VDLType_struct_1); err != nil {
return err
}
if x.Str != "" {
@@ -95,7 +94,7 @@
}
func __VDLWriteAnon_list_1(enc vdl.Encoder, x []uint32) error {
- if err := enc.StartValue(vdl.TypeOf((*[]uint32)(nil))); err != nil {
+ if err := enc.StartValue(__VDLType_list_2); err != nil {
return err
}
if err := enc.SetLenHint(len(x)); err != nil {
@@ -123,12 +122,9 @@
func (x *ComplexErrorParam) VDLRead(dec vdl.Decoder) error {
*x = ComplexErrorParam{}
- if err := dec.StartValue(); err != nil {
+ if err := dec.StartValue(__VDLType_struct_1); err != nil {
return err
}
- if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
- return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
- }
for {
f, err := dec.NextField()
if err != nil {
@@ -138,7 +134,7 @@
case "":
return dec.FinishValue()
case "Str":
- if err := dec.StartValue(); err != nil {
+ if err := dec.StartValue(vdl.StringType); err != nil {
return err
}
var err error
@@ -149,7 +145,7 @@
return err
}
case "Num":
- if err := dec.StartValue(); err != nil {
+ if err := dec.StartValue(vdl.Int32Type); err != nil {
return err
}
tmp, err := dec.DecodeInt(32)
@@ -173,12 +169,9 @@
}
func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]uint32) error {
- if err := dec.StartValue(); err != nil {
+ if err := dec.StartValue(__VDLType_list_2); err != nil {
return err
}
- if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
- return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
- }
switch len := dec.LenHint(); {
case len > 0:
*x = make([]uint32, 0, len)
@@ -193,7 +186,7 @@
return dec.FinishValue()
}
var elem uint32
- if err := dec.StartValue(); err != nil {
+ if err := dec.StartValue(vdl.Uint32Type); err != nil {
return err
}
tmp, err := dec.DecodeUint(32)
@@ -928,6 +921,12 @@
return s.s.Send(item)
}
+// Hold type definitions in package-level variables, for better performance.
+var (
+ __VDLType_struct_1 *vdl.Type
+ __VDLType_list_2 *vdl.Type
+)
+
var __VDLInitCalled bool
// __VDLInit performs vdl initialization. It is safe to call multiple times.
@@ -952,6 +951,10 @@
// Register types.
vdl.Register((*ComplexErrorParam)(nil))
+ // Initialize type definitions.
+ __VDLType_struct_1 = vdl.TypeOf((*ComplexErrorParam)(nil)).Elem()
+ __VDLType_list_2 = vdl.TypeOf((*[]uint32)(nil))
+
// Set error format strings.
i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoFortunes.ID), "{1:}{2:} no fortunes added")
i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrComplex.ID), "{1:}{2:} this is a complex error with params {3} {4} {5}")