{"id":13459775,"url":"https://github.com/mailru/easyjson","last_synced_at":"2025-05-12T16:24:47.722Z","repository":{"id":39702189,"uuid":"52589524","full_name":"mailru/easyjson","owner":"mailru","description":"Fast JSON serializer for golang.","archived":false,"fork":false,"pushed_at":"2025-01-11T19:28:08.000Z","size":472,"stargazers_count":4673,"open_issues_count":84,"forks_count":436,"subscribers_count":85,"default_branch":"master","last_synced_at":"2025-05-05T14:18:27.965Z","etag":null,"topics":["code-generation","golang","json","json-parser","json-serialization","perfomance"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mailru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-26T08:19:26.000Z","updated_at":"2025-05-05T13:12:05.000Z","dependencies_parsed_at":"2024-06-18T10:49:23.700Z","dependency_job_id":"b497ef29-8e07-4922-a8ca-d32388c983fc","html_url":"https://github.com/mailru/easyjson","commit_stats":{"total_commits":296,"total_committers":100,"mean_commits":2.96,"dds":0.9222972972972973,"last_synced_commit":"141f9c7d7ffebf0474bfbc15e7adcbcabf8fc0ee"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Feasyjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Feasyjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Feasyjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mailru%2Feasyjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mailru","download_url":"https://codeload.github.com/mailru/easyjson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253774877,"owners_count":21962245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-generation","golang","json","json-parser","json-serialization","perfomance"],"created_at":"2024-07-31T10:00:28.899Z","updated_at":"2025-05-12T16:24:47.703Z","avatar_url":"https://github.com/mailru.png","language":"Go","readme":"# easyjson [![Build Status](https://github.com/mailru/easyjson/actions/workflows/easyjson.yml/badge.svg)](https://github.com/mailru/easyjson/actions/workflows/easyjson.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/mailru/easyjson)](https://goreportcard.com/report/github.com/mailru/easyjson)\n\nPackage easyjson provides a fast and easy way to marshal/unmarshal Go structs\nto/from JSON without the use of reflection. In performance tests, easyjson\noutperforms the standard `encoding/json` package by a factor of 4-5x, and other\nJSON encoding packages by a factor of 2-3x.\n\neasyjson aims to keep generated Go code simple enough so that it can be easily\noptimized or fixed. Another goal is to provide users with the ability to\ncustomize the generated code by providing options not available with the\nstandard `encoding/json` package, such as generating \"snake_case\" names or\nenabling `omitempty` behavior by default.\n\n## Usage\n### Install: \n```sh\n# for Go \u003c 1.17\ngo get -u github.com/mailru/easyjson/...\n```\n#### or\n```sh\n# for Go \u003e= 1.17\ngo get github.com/mailru/easyjson \u0026\u0026 go install github.com/mailru/easyjson/...@latest\n```\n### Run:\n```sh\neasyjson -all \u003cfile\u003e.go\n```\n\nThe above will generate `\u003cfile\u003e_easyjson.go` containing the appropriate marshaler and\nunmarshaler funcs for all structs contained in `\u003cfile\u003e.go`.\n\nPlease note that easyjson requires a full Go build environment and the `GOPATH`\nenvironment variable to be set. This is because easyjson code generation\ninvokes `go run` on a temporary file (an approach to code generation borrowed\nfrom [ffjson](https://github.com/pquerna/ffjson)).\n\n### Serialize\n```go\nsomeStruct := \u0026SomeStruct{Field1: \"val1\", Field2: \"val2\"}\nrawBytes, err := easyjson.Marshal(someStruct)\n```\n\n### Deserialize\n```go\nsomeStruct := \u0026SomeStruct{}\nerr := easyjson.Unmarshal(rawBytes, someStruct)\n```\n\nPlease see the [GoDoc](https://godoc.org/github.com/mailru/easyjson)\nfor more information and features.\n## Options\n```txt\nUsage of easyjson:\n  -all\n    \tgenerate marshaler/unmarshalers for all structs in a file\n  -build_tags string\n        build tags to add to generated file\n  -gen_build_flags string\n        build flags when running the generator while bootstrapping\n  -byte\n        use simple bytes instead of Base64Bytes for slice of bytes\n  -leave_temps\n    \tdo not delete temporary files\n  -no_std_marshalers\n    \tdon't generate MarshalJSON/UnmarshalJSON funcs\n  -noformat\n    \tdo not run 'gofmt -w' on output file\n  -omit_empty\n    \tomit empty fields by default\n  -output_filename string\n    \tspecify the filename of the output\n  -pkg\n    \tprocess the whole package instead of just the given file\n  -snake_case\n    \tuse snake_case names instead of CamelCase by default\n  -lower_camel_case\n        use lowerCamelCase instead of CamelCase by default\n  -stubs\n    \tonly generate stubs for marshaler/unmarshaler funcs\n  -disallow_unknown_fields\n        return error if some unknown field in json appeared\n  -disable_members_unescape\n        disable unescaping of \\uXXXX string sequences in member names\n```\n\nUsing `-all` will generate marshalers/unmarshalers for all Go structs in the\nfile excluding those structs whose preceding comment starts with `easyjson:skip`.\nFor example: \n\n```go\n//easyjson:skip\ntype A struct {}\n```\n\nIf `-all` is not provided, then only those structs whose preceding\ncomment starts with `easyjson:json` will have marshalers/unmarshalers\ngenerated. For example:\n\n```go\n//easyjson:json\ntype A struct {}\n```\n\nAdditional option notes:\n\n* `-snake_case` tells easyjson to generate snake\\_case field names by default\n  (unless overridden by a field tag). The CamelCase to snake\\_case conversion\n  algorithm should work in most cases (ie, HTTPVersion will be converted to\n  \"http_version\").\n\n* `-build_tags` will add the specified build tags to generated Go sources.\n\n* `-gen_build_flags` will execute the easyjson bootstapping code to launch the \n  actual generator command with provided flags. Multiple arguments should be\n  separated by space e.g. `-gen_build_flags=\"-mod=mod -x\"`.\n\n## Structure json tag options\n\nBesides standard json tag options like 'omitempty' the following are supported:\n\n* 'nocopy' - disables allocation and copying of string values, making them\n  refer to original json buffer memory. This works great for short lived\n  objects which are not hold in memory after decoding and immediate usage.\n  Note if string requires unescaping it will be processed as normally.\n* 'intern' - string \"interning\" (deduplication) to save memory when the very\n  same string dictionary values are often met all over the structure.\n  See below for more details.\n\n## Generated Marshaler/Unmarshaler Funcs\n\nFor Go struct types, easyjson generates the funcs `MarshalEasyJSON` /\n`UnmarshalEasyJSON` for marshaling/unmarshaling JSON. In turn, these satisfy\nthe `easyjson.Marshaler` and `easyjson.Unmarshaler` interfaces and when used in\nconjunction with `easyjson.Marshal` / `easyjson.Unmarshal` avoid unnecessary\nreflection / type assertions during marshaling/unmarshaling to/from JSON for Go\nstructs.\n\neasyjson also generates `MarshalJSON` and `UnmarshalJSON` funcs for Go struct\ntypes compatible with the standard `json.Marshaler` and `json.Unmarshaler`\ninterfaces. Please be aware that using the standard `json.Marshal` /\n`json.Unmarshal` for marshaling/unmarshaling will incur a significant\nperformance penalty when compared to using `easyjson.Marshal` /\n`easyjson.Unmarshal`.\n\nAdditionally, easyjson exposes utility funcs that use the `MarshalEasyJSON` and\n`UnmarshalEasyJSON` for marshaling/unmarshaling to and from standard readers\nand writers. For example, easyjson provides `easyjson.MarshalToHTTPResponseWriter`\nwhich marshals to the standard `http.ResponseWriter`. Please see the [GoDoc\nlisting](https://godoc.org/github.com/mailru/easyjson) for the full listing of\nutility funcs that are available.\n\n## Controlling easyjson Marshaling and Unmarshaling Behavior\n\nGo types can provide their own `MarshalEasyJSON` and `UnmarshalEasyJSON` funcs\nthat satisfy the `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces.\nThese will be used by `easyjson.Marshal` and `easyjson.Unmarshal` when defined\nfor a Go type.\n\nGo types can also satisfy the `easyjson.Optional` interface, which allows the\ntype to define its own `omitempty` logic.\n\n## Type Wrappers\n\neasyjson provides additional type wrappers defined in the `easyjson/opt`\npackage. These wrap the standard Go primitives and in turn satisfy the\neasyjson interfaces.\n\nThe `easyjson/opt` type wrappers are useful when needing to distinguish between\na missing value and/or when needing to specifying a default value. Type\nwrappers allow easyjson to avoid additional pointers and heap allocations and\ncan significantly increase performance when used properly.\n\n## Memory Pooling\n\neasyjson uses a buffer pool that allocates data in increasing chunks from 128\nto 32768 bytes. Chunks of 512 bytes and larger will be reused with the help of\n`sync.Pool`. The maximum size of a chunk is bounded to reduce redundant memory\nallocation and to allow larger reusable buffers.\n\neasyjson's custom allocation buffer pool is defined in the `easyjson/buffer`\npackage, and the default behavior pool behavior can be modified (if necessary)\nthrough a call to `buffer.Init()` prior to any marshaling or unmarshaling.\nPlease see the [GoDoc listing](https://godoc.org/github.com/mailru/easyjson/buffer)\nfor more information.\n\n## String interning\n\nDuring unmarshaling, `string` field values can be optionally\n[interned](https://en.wikipedia.org/wiki/String_interning) to reduce memory\nallocations and usage by deduplicating strings in memory, at the expense of slightly\nincreased CPU usage.\n\nThis will work effectively only for `string` fields being decoded that have frequently\nthe same value (e.g. if you have a string field that can only assume a small number\nof possible values).\n\nTo enable string interning, add the `intern` keyword tag to your `json` tag on `string`\nfields, e.g.:\n\n```go\ntype Foo struct {\n  UUID  string `json:\"uuid\"`         // will not be interned during unmarshaling\n  State string `json:\"state,intern\"` // will be interned during unmarshaling\n}\n```\n\n## Issues, Notes, and Limitations\n\n* easyjson is still early in its development. As such, there are likely to be\n  bugs and missing features when compared to `encoding/json`. In the case of a\n  missing feature or bug, please create a GitHub issue. Pull requests are\n  welcome!\n\n* Unlike `encoding/json`, object keys are case-sensitive. Case-insensitive\n  matching is not currently provided due to the significant performance hit\n  when doing case-insensitive key matching. In the future, case-insensitive\n  object key matching may be provided via an option to the generator.\n\n* easyjson makes use of `unsafe`, which simplifies the code and\n  provides significant performance benefits by allowing no-copy\n  conversion from `[]byte` to `string`. That said, `unsafe` is used\n  only when unmarshaling and parsing JSON, and any `unsafe` operations\n  / memory allocations done will be safely deallocated by\n  easyjson. Set the build tag `easyjson_nounsafe` to compile it\n  without `unsafe`.\n\n* easyjson is compatible with Google App Engine. The `appengine` build\n  tag (set by App Engine's environment) will automatically disable the\n  use of `unsafe`, which is not allowed in App Engine's Standard\n  Environment. Note that the use with App Engine is still experimental.\n\n* Floats are formatted using the default precision from Go's `strconv` package.\n  As such, easyjson will not correctly handle high precision floats when\n  marshaling/unmarshaling JSON. Note, however, that there are very few/limited\n  uses where this behavior is not sufficient for general use. That said, a\n  different package may be needed if precise marshaling/unmarshaling of high\n  precision floats to/from JSON is required.\n\n* While unmarshaling, the JSON parser does the minimal amount of work needed to\n  skip over unmatching parens, and as such full validation is not done for the\n  entire JSON value being unmarshaled/parsed.\n\n* Currently there is no true streaming support for encoding/decoding as\n  typically for many uses/protocols the final, marshaled length of the JSON\n  needs to be known prior to sending the data. Currently this is not possible\n  with easyjson's architecture.\n  \n* easyjson parser and codegen based on reflection, so it won't work on `package main` \n  files, because they cant be imported by parser.\n\n## Benchmarks\n\nMost benchmarks were done using the example\n[13kB example JSON](https://dev.twitter.com/rest/reference/get/search/tweets)\n(9k after eliminating whitespace). This example is similar to real-world data,\nis well-structured, and contains a healthy variety of different types, making\nit ideal for JSON serialization benchmarks.\n\nNote:\n\n* For small request benchmarks, an 80 byte portion of the above example was\n  used.\n\n* For large request marshaling benchmarks, a struct containing 50 regular\n  samples was used, making a ~500kB output JSON.\n\n* Benchmarks are showing the results of easyjson's default behaviour,\n  which makes use of `unsafe`.\n\nBenchmarks are available in the repository and can be run by invoking `make`.\n\n### easyjson vs. encoding/json\n\neasyjson is roughly 5-6 times faster than the standard `encoding/json` for\nunmarshaling, and 3-4 times faster for non-concurrent marshaling. Concurrent\nmarshaling is 6-7x faster if marshaling to a writer.\n\n### easyjson vs. ffjson\n\neasyjson uses the same approach for JSON marshaling as\n[ffjson](https://github.com/pquerna/ffjson), but takes a significantly\ndifferent approach to lexing and parsing JSON during unmarshaling. This means\neasyjson is roughly 2-3x faster for unmarshaling and 1.5-2x faster for\nnon-concurrent unmarshaling.\n\nAs of this writing, `ffjson` seems to have issues when used concurrently:\nspecifically, large request pooling hurts `ffjson`'s performance and causes\nscalability issues. These issues with `ffjson` can likely be fixed, but as of\nwriting remain outstanding/known issues with `ffjson`.\n\neasyjson and `ffjson` have similar performance for small requests, however\neasyjson outperforms `ffjson` by roughly 2-5x times for large requests when\nused with a writer.\n\n### easyjson vs. go/codec\n\n[go/codec](https://github.com/ugorji/go) provides\ncompile-time helpers for JSON generation. In this case, helpers do not work\nlike marshalers as they are encoding-independent.\n\neasyjson is generally 2x faster than `go/codec` for non-concurrent benchmarks\nand about 3x faster for concurrent encoding (without marshaling to a writer).\n\nIn an attempt to measure marshaling performance of `go/codec` (as opposed to\nallocations/memcpy/writer interface invocations), a benchmark was done with\nresetting length of a byte slice rather than resetting the whole slice to nil.\nHowever, the optimization in this exact form may not be applicable in practice,\nsince the memory is not freed between marshaling operations.\n\n### easyjson vs 'ujson' python module\n\n[ujson](https://github.com/esnme/ultrajson) is using C code for parsing, so it\nis interesting to see how plain golang compares to that. It is important to note\nthat the resulting object for python is slower to access, since the library\nparses JSON object into dictionaries.\n\neasyjson is slightly faster for unmarshaling and 2-3x faster than `ujson` for\nmarshaling.\n\n### Benchmark Results\n\n`ffjson` results are from February 4th, 2016, using the latest `ffjson` and go1.6.\n`go/codec` results are from March 4th, 2016, using the latest `go/codec` and go1.6.\n\n#### Unmarshaling\n\n| lib      | json size | MB/s | allocs/op | B/op  |\n|:---------|:----------|-----:|----------:|------:|\n| standard | regular   | 22   | 218       | 10229 |\n| standard | small     | 9.7  | 14        | 720   |\n|          |           |      |           |       |\n| easyjson | regular   | 125  | 128       | 9794  |\n| easyjson | small     | 67   | 3         | 128   |\n|          |           |      |           |       |\n| ffjson   | regular   | 66   | 141       | 9985  |\n| ffjson   | small     | 17.6 | 10        | 488   |\n|          |           |      |           |       |\n| codec    | regular   | 55   | 434       | 19299 |\n| codec    | small     | 29   | 7         | 336   |\n|          |           |      |           |       |\n| ujson    | regular   | 103  | N/A       | N/A   |\n\n#### Marshaling, one goroutine.\n\n| lib       | json size | MB/s | allocs/op | B/op  |\n|:----------|:----------|-----:|----------:|------:|\n| standard  | regular   | 75   | 9         | 23256 |\n| standard  | small     | 32   | 3         | 328   |\n| standard  | large     | 80   | 17        | 1.2M  |\n|           |           |      |           |       |\n| easyjson  | regular   | 213  | 9         | 10260 |\n| easyjson* | regular   | 263  | 8         | 742   |\n| easyjson  | small     | 125  | 1         | 128   |\n| easyjson  | large     | 212  | 33        | 490k  |\n| easyjson* | large     | 262  | 25        | 2879  |\n|           |           |      |           |       |\n| ffjson    | regular   | 122  | 153       | 21340 |\n| ffjson**  | regular   | 146  | 152       | 4897  |\n| ffjson    | small     | 36   | 5         | 384   |\n| ffjson**  | small     | 64   | 4         | 128   |\n| ffjson    | large     | 134  | 7317      | 818k  |\n| ffjson**  | large     | 125  | 7320      | 827k  |\n|           |           |      |           |       |\n| codec     | regular   | 80   | 17        | 33601 |\n| codec***  | regular   | 108  | 9         | 1153  |\n| codec     | small     | 42   | 3         | 304   |\n| codec***  | small     | 56   | 1         | 48    |\n| codec     | large     | 73   | 483       | 2.5M  |\n| codec***  | large     | 103  | 451       | 66007 |\n|           |           |      |           |       |\n| ujson     | regular   | 92   | N/A       | N/A   |\n\n\\* marshaling to a writer,\n\\*\\* using `ffjson.Pool()`,\n\\*\\*\\* reusing output slice instead of resetting it to nil\n\n#### Marshaling, concurrent.\n\n| lib       | json size | MB/s | allocs/op | B/op  |\n|:----------|:----------|-----:|----------:|------:|\n| standard  | regular   | 252  | 9         | 23257 |\n| standard  | small     | 124  | 3         | 328   |\n| standard  | large     | 289  | 17        | 1.2M  |\n|           |           |      |           |       |\n| easyjson  | regular   | 792  | 9         | 10597 |\n| easyjson* | regular   | 1748 | 8         | 779   |\n| easyjson  | small     | 333  | 1         | 128   |\n| easyjson  | large     | 718  | 36        | 548k  |\n| easyjson* | large     | 2134 | 25        | 4957  |\n|           |           |      |           |       |\n| ffjson    | regular   | 301  | 153       | 21629 |\n| ffjson**  | regular   | 707  | 152       | 5148  |\n| ffjson    | small     | 62   | 5         | 384   |\n| ffjson**  | small     | 282  | 4         | 128   |\n| ffjson    | large     | 438  | 7330      | 1.0M  |\n| ffjson**  | large     | 131  | 7319      | 820k  |\n|           |           |      |           |       |\n| codec     | regular   | 183  | 17        | 33603 |\n| codec***  | regular   | 671  | 9         | 1157  |\n| codec     | small     | 147  | 3         | 304   |\n| codec***  | small     | 299  | 1         | 48    |\n| codec     | large     | 190  | 483       | 2.5M  |\n| codec***  | large     | 752  | 451       | 77574 |\n\n\\* marshaling to a writer,\n\\*\\* using `ffjson.Pool()`,\n\\*\\*\\* reusing output slice instead of resetting it to nil\n","funding_links":[],"categories":["开源类库","Go","HarmonyOS","JSON parsers \u0026 validators","Open source library","\u003e 1k ★","语言资源库","Encoders","Инструменты разработчика"],"sub_categories":["JSON","Windows Manager","go","Instrumentation and control with sensors and actuators"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailru%2Feasyjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmailru%2Feasyjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmailru%2Feasyjson/lists"}