mirror of
https://github.com/netbirdio/easyjson.git
synced 2026-05-22 18:44:42 -07:00
Add new -disable_members_unescape option to avoid unescaping of member names, ints, ...
Improves performance for about 15% on BenchmarkEJ_Unmarshal_M-8
This commit is contained in:
@@ -28,7 +28,7 @@ generate: build
|
||||
bin/easyjson -all ./tests/html.go
|
||||
bin/easyjson -snake_case ./tests/snake.go
|
||||
bin/easyjson -omit_empty ./tests/omitempty.go
|
||||
bin/easyjson -build_tags=use_easyjson ./benchmark/data.go
|
||||
bin/easyjson -build_tags=use_easyjson -disable_members_unescape ./benchmark/data.go
|
||||
bin/easyjson ./tests/nested_easy.go
|
||||
bin/easyjson ./tests/named_type.go
|
||||
bin/easyjson ./tests/custom_map_key_type.go
|
||||
|
||||
+12
-8
@@ -23,18 +23,19 @@ type Generator struct {
|
||||
PkgPath, PkgName string
|
||||
Types []string
|
||||
|
||||
NoStdMarshalers bool
|
||||
SnakeCase bool
|
||||
LowerCamelCase bool
|
||||
OmitEmpty bool
|
||||
DisallowUnknownFields bool
|
||||
NoStdMarshalers bool
|
||||
SnakeCase bool
|
||||
LowerCamelCase bool
|
||||
OmitEmpty bool
|
||||
DisallowUnknownFields bool
|
||||
SkipMemberNameUnescaping bool
|
||||
|
||||
OutName string
|
||||
BuildTags string
|
||||
|
||||
StubsOnly bool
|
||||
LeaveTemps bool
|
||||
NoFormat bool
|
||||
StubsOnly bool
|
||||
LeaveTemps bool
|
||||
NoFormat bool
|
||||
SimpleBytes bool
|
||||
}
|
||||
|
||||
@@ -129,6 +130,9 @@ func (g *Generator) writeMain() (path string, err error) {
|
||||
if g.SimpleBytes {
|
||||
fmt.Fprintln(f, " g.SimpleBytes()")
|
||||
}
|
||||
if g.SkipMemberNameUnescaping {
|
||||
fmt.Fprintln(f, " g.SkipMemberNameUnescaping()")
|
||||
}
|
||||
|
||||
sort.Strings(g.Types)
|
||||
for _, v := range g.Types {
|
||||
|
||||
+16
-14
@@ -29,6 +29,7 @@ var noformat = flag.Bool("noformat", false, "do not run 'gofmt -w' on output fil
|
||||
var specifiedName = flag.String("output_filename", "", "specify the filename of the output")
|
||||
var processPkg = flag.Bool("pkg", false, "process the whole package instead of just the given file")
|
||||
var disallowUnknownFields = flag.Bool("disallow_unknown_fields", false, "return error if any unknown field in json appeared")
|
||||
var skipMemberNameUnescaping = flag.Bool("disable_members_unescape", false, "don't perform unescaping of member names to improve performance")
|
||||
|
||||
func generate(fname string) (err error) {
|
||||
fInfo, err := os.Stat(fname)
|
||||
@@ -62,20 +63,21 @@ func generate(fname string) (err error) {
|
||||
}
|
||||
|
||||
g := bootstrap.Generator{
|
||||
BuildTags: trimmedBuildTags,
|
||||
PkgPath: p.PkgPath,
|
||||
PkgName: p.PkgName,
|
||||
Types: p.StructNames,
|
||||
SnakeCase: *snakeCase,
|
||||
LowerCamelCase: *lowerCamelCase,
|
||||
NoStdMarshalers: *noStdMarshalers,
|
||||
DisallowUnknownFields: *disallowUnknownFields,
|
||||
OmitEmpty: *omitEmpty,
|
||||
LeaveTemps: *leaveTemps,
|
||||
OutName: outName,
|
||||
StubsOnly: *stubs,
|
||||
NoFormat: *noformat,
|
||||
SimpleBytes: *simpleBytes,
|
||||
BuildTags: trimmedBuildTags,
|
||||
PkgPath: p.PkgPath,
|
||||
PkgName: p.PkgName,
|
||||
Types: p.StructNames,
|
||||
SnakeCase: *snakeCase,
|
||||
LowerCamelCase: *lowerCamelCase,
|
||||
NoStdMarshalers: *noStdMarshalers,
|
||||
DisallowUnknownFields: *disallowUnknownFields,
|
||||
SkipMemberNameUnescaping: *skipMemberNameUnescaping,
|
||||
OmitEmpty: *omitEmpty,
|
||||
LeaveTemps: *leaveTemps,
|
||||
OutName: outName,
|
||||
StubsOnly: *stubs,
|
||||
NoFormat: *noformat,
|
||||
SimpleBytes: *simpleBytes,
|
||||
}
|
||||
|
||||
if err := g.Run(); err != nil {
|
||||
|
||||
@@ -457,6 +457,9 @@ func (g *Generator) genStructDecoder(t reflect.Type) error {
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
|
||||
if g.skipMemberNameUnescaping {
|
||||
fmt.Fprintln(g.out, " in.SkipUnescape = true")
|
||||
}
|
||||
fmt.Fprintln(g.out, " isTopLevel := in.IsStart()")
|
||||
fmt.Fprintln(g.out, " if in.IsNull() {")
|
||||
fmt.Fprintln(g.out, " if isTopLevel {")
|
||||
|
||||
+11
-5
@@ -33,11 +33,12 @@ type Generator struct {
|
||||
|
||||
varCounter int
|
||||
|
||||
noStdMarshalers bool
|
||||
omitEmpty bool
|
||||
disallowUnknownFields bool
|
||||
fieldNamer FieldNamer
|
||||
simpleBytes bool
|
||||
noStdMarshalers bool
|
||||
omitEmpty bool
|
||||
disallowUnknownFields bool
|
||||
fieldNamer FieldNamer
|
||||
simpleBytes bool
|
||||
skipMemberNameUnescaping bool
|
||||
|
||||
// package path to local alias map for tracking imports
|
||||
imports map[string]string
|
||||
@@ -117,6 +118,11 @@ func (g *Generator) DisallowUnknownFields() {
|
||||
g.disallowUnknownFields = true
|
||||
}
|
||||
|
||||
// SkipMemberNameUnescaping instructs to skip member names unescaping to improve performance
|
||||
func (g *Generator) SkipMemberNameUnescaping() {
|
||||
g.skipMemberNameUnescaping = true
|
||||
}
|
||||
|
||||
// OmitEmpty triggers `json=",omitempty"` behaviour by default.
|
||||
func (g *Generator) OmitEmpty() {
|
||||
g.omitEmpty = true
|
||||
|
||||
+6
-3
@@ -49,6 +49,7 @@ type Lexer struct {
|
||||
|
||||
firstElement bool // Whether current element is the first in array or an object.
|
||||
wantSep byte // A comma or a colon character, which need to occur before a token.
|
||||
SkipUnescape bool // Skip unescaping on all but user returned strings (i.e. member names, numbers, bytes etc.)
|
||||
|
||||
UseMultipleErrors bool // If we want to use multiple errors.
|
||||
fatalError error // Fatal error occurred during lexing. It is usually a syntax error.
|
||||
@@ -606,9 +607,11 @@ func (r *Lexer) unsafeString() (string, []byte) {
|
||||
r.errInvalidToken("string")
|
||||
return "", nil
|
||||
}
|
||||
if err := r.unescapeStringToken(); err != nil {
|
||||
r.errInvalidToken("string")
|
||||
return "", nil
|
||||
if !r.SkipUnescape {
|
||||
if err := r.unescapeStringToken(); err != nil {
|
||||
r.errInvalidToken("string")
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
|
||||
bytes := r.token.byteValue
|
||||
|
||||
Reference in New Issue
Block a user