Skip to content

Commit

Permalink
codec: change field switch code
Browse files Browse the repository at this point in the history
The code for decoding struct fields is now a switch with contiguous
constants.

Although the Go compiler doesn't yet generate jump tables, it
hopefully will someday (golang/go#5496), and these switches will get
faster.

Also, fix registration of benchmark types.
  • Loading branch information
jba committed Feb 15, 2021
1 parent fb5afb1 commit e369626
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 77 deletions.
108 changes: 54 additions & 54 deletions internal/benchmarks/data/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,60 +21,60 @@ import (
var ASTData = gobBenchmarkData("ast", func() interface{} { return new(map[string]*ast.File) })

var astTypes = []interface{}{
ast.ArrayType{},
ast.AssignStmt{},
ast.BadDecl{},
ast.BadExpr{},
ast.BadStmt{},
ast.BasicLit{},
ast.BinaryExpr{},
ast.BlockStmt{},
ast.BranchStmt{},
ast.CallExpr{},
ast.CaseClause{},
ast.ChanType{},
ast.CommClause{},
ast.CommentGroup{},
ast.Comment{},
ast.CompositeLit{},
ast.DeclStmt{},
ast.DeferStmt{},
ast.Ellipsis{},
ast.EmptyStmt{},
ast.ExprStmt{},
ast.FieldList{},
ast.Field{},
ast.ForStmt{},
ast.FuncDecl{},
ast.FuncLit{},
ast.FuncType{},
ast.GenDecl{},
ast.GoStmt{},
ast.Ident{},
ast.IfStmt{},
ast.ImportSpec{},
ast.IncDecStmt{},
ast.IndexExpr{},
ast.InterfaceType{},
ast.KeyValueExpr{},
ast.LabeledStmt{},
ast.MapType{},
ast.ParenExpr{},
ast.RangeStmt{},
ast.ReturnStmt{},
ast.Scope{},
ast.SelectStmt{},
ast.SelectorExpr{},
ast.SendStmt{},
ast.SliceExpr{},
ast.StarExpr{},
ast.StructType{},
ast.SwitchStmt{},
ast.TypeAssertExpr{},
ast.TypeSpec{},
ast.TypeSwitchStmt{},
ast.UnaryExpr{},
ast.ValueSpec{},
&ast.ArrayType{},
&ast.AssignStmt{},
&ast.BadDecl{},
&ast.BadExpr{},
&ast.BadStmt{},
&ast.BasicLit{},
&ast.BinaryExpr{},
&ast.BlockStmt{},
&ast.BranchStmt{},
&ast.CallExpr{},
&ast.CaseClause{},
&ast.ChanType{},
&ast.CommClause{},
&ast.CommentGroup{},
&ast.Comment{},
&ast.CompositeLit{},
&ast.DeclStmt{},
&ast.DeferStmt{},
&ast.Ellipsis{},
&ast.EmptyStmt{},
&ast.ExprStmt{},
&ast.FieldList{},
&ast.Field{},
&ast.ForStmt{},
&ast.FuncDecl{},
&ast.FuncLit{},
&ast.FuncType{},
&ast.GenDecl{},
&ast.GoStmt{},
&ast.Ident{},
&ast.IfStmt{},
&ast.ImportSpec{},
&ast.IncDecStmt{},
&ast.IndexExpr{},
&ast.InterfaceType{},
&ast.KeyValueExpr{},
&ast.LabeledStmt{},
&ast.MapType{},
&ast.ParenExpr{},
&ast.RangeStmt{},
&ast.ReturnStmt{},
&ast.Scope{},
&ast.SelectStmt{},
&ast.SelectorExpr{},
&ast.SendStmt{},
&ast.SliceExpr{},
&ast.StarExpr{},
&ast.StructType{},
&ast.SwitchStmt{},
&ast.TypeAssertExpr{},
&ast.TypeSpec{},
&ast.TypeSwitchStmt{},
&ast.UnaryExpr{},
&ast.ValueSpec{},
}

func init() {
Expand Down
2 changes: 1 addition & 1 deletion internal/benchmarks/data/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func Generate(words []string) error {
switch w {
case "code":
err = codec.GenerateFile("types.gen.go", thisPkgPath, nil,
LicenseData{}, submittedData{}, []*StockData(nil), []Score(nil))
&LicenseData{}, submittedData{}, []*StockData(nil), []Score(nil))
if err == nil {
err = codec.GenerateFile("ast_types.gen.go", thisPkgPath, nil,
append(astTypes, map[string]*ast.File{})...)
Expand Down
13 changes: 8 additions & 5 deletions struct.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,21 @@ func (c *«$typeName») Decode(d *codecapi.Decoder) interface{} {

func (c *«$typeName») decode(d *codecapi.Decoder, x *«$goName») {
d.StartStruct()
for {
loop: for {
n := d.NextStructField(c.fieldMap)
if n == -1 { break }
switch n {
«range $i, $f := .Fields -»
«- if $f.Type -»
case «$i»:
«decodeStmt $f.Type (print "x." $f.Name)»
case «$i»:
«decodeStmt $f.Type (print "x." $f.Name)»
«end -»
«end -»
default:
case -1:
break loop
case -2:
d.UnknownField("«$goName»", n)
default:
codecapi.Failf("bad struct field value: %d", n)
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions struct_body.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions testdata/struct.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions testdata/structmap.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions testdata/structslice.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e369626

Please sign in to comment.