Fast and flexible JSON encoder for Go

Overview

Jettison

GoCaptain

Jettison is a fast and flexible JSON encoder for the Go programming language, inspired by bet365/jingo, with a richer features set, aiming at 100% compatibility with the standard library.



Installation

Jettison uses the new Go modules. Releases are tagged according to the SemVer format, prefixed with a v, starting from 0.2.0. You can get the latest release using the following command.

$ go get github.com/wI2L/jettison

Key features

  • Fast, see benchmarks
  • No dynamic memory allocations in hot paths
  • Behavior identical to the standard library by default
  • No code generation required
  • Clear and concise API
  • Configurable with opt-in functional options
  • Native support for many standard library types, see improvements
  • Custom AppendMarshaler interface to avoid allocations
  • Extensive testsuite that compares its output against encoding/json

Overview

The goal of Jettision is to take up the idea introduced by the bet365/jingo package and build a fully-featured JSON encoder around it, that comply with the behavior of the encoding/json package. Unlike the latter, Jettison does not use reflection during marshaling, but only once to create the instruction set for a given type ahead of time. The drawback to this approach requires to instantiate an instruction-set once for each type that needs to be marshaled, but that is overcomed with a package cache.

The package aims to have a behavior similar to that of the standard library for all types encoding and struct tags, meaning that the documentation of the json.Marshal function is applicable for Jettison, with a few exceptions described in this section. As such, most of the tests compare their output against it to guarantee that.

Implementation details

The main concept of Jettison consists of using pre-build instructions-set to reduce the cost of using the reflect package at runtime. When marshaling a value, a set of instructions is recursively generated for its type, which defines how to iteratively encode it. An instruction is a function or a closure, that have all the information required to read the data from memory using unsafe operations (pointer type conversion, arithmetic...) during the instruction set execution.

Differences with encoding/json

All notable differences with the standard library behavior are listed below. Please note that these might evolve with future versions of the package.

Improvements

  • The time.Time and time.Duration types are handled natively. For time values, the encoder doesn't invoke MarshalJSON or MarshalText, but use the time.AppendFormat function instead, and write the result to the stream. Similarly, for durations, it isn't necessary to implements the json.Marshaler or encoding.TextMarshaler interfaces on a custom wrapper type, the encoder uses the result of one of the methods Minutes, Seconds, Nanoseconds or String, based on the duration format configured.

  • The sync.Map type is handled natively. The marshaling behavior is similar to the one of a standard Go map. The option UnsortedMap can also be used in cunjunction with this type to disable the default keys sort.

  • The omitnil field tag's option can be used to specify that a field with a nil pointer should be omitted from the encoding. This option has precedence over the omitempty option.

Bugs

Go1.13 and backward
  • Nil map keys values implementing the encoding.TextMarshaler interface are encoded as empty strings, while the encoding/json package currently panic because of that. See this issue for more details.[1]

  • Nil struct fields implementing the encoding.TextMarshaler interface are encoded as null, while the encoding/json package currently panic because of that. See this issue for more details.[1]

1: The issues mentioned above have had their associated CL merged, and should be shipped with Go 1.14.

Usage

Basic

As stated above, the library behave similarly to the encoding/json package. You can simply replace the json.Marshal function with jettison.Marshal, and expect the same output with better performances.

type X struct {
   A string `json:"a"`
   B int64  `json:"b"`
}
b, err := jettison.Marshal(X{
   A: "Loreum",
   B: 42,
})
if err != nil {
   log.Fatal(err)
}
os.Stdout.Write(b)
Result
{"a":"Loreum","b":42}

Advanced

If more control over the encoding behavior is required, use the MarshalOpts function instead. The second parameter is variadic and accept a list of functional opt-in options described below:

name description
TimeLayout Defines the layout used to encode time.Time values. The layout must be compatible with the AppendFormat method.
DurationFormat Defines the format used to encode time.Duration values. See the documentation of the DurationFmt type for the complete list of formats available.
UnixTime Encode time.Time values as JSON numbers representing Unix timestamps, the number of seconds elapsed since January 1, 1970 UTC. This option has precedence over TimeLayout.
UnsortedMap Disables map keys sort.
ByteArrayAsString Encodes byte arrays as JSON strings rather than JSON arrays. The output is subject to the same escaping rules used for JSON strings, unless the option NoStringEscaping is used.
RawByteSlice Disables the base64 default encoding used for byte slices.
NilMapEmpty Encodes nil Go maps as empty JSON objects rather than null.
NilSliceEmpty Encodes nil Go slices as empty JSON arrays rather than null.
NoStringEscaping Disables string escaping. NoHTMLEscaping and NoUTF8Coercion are ignored when this option is used.
NoHTMLEscaping Disables the escaping of special HTML characters such as &, < and > in JSON strings. This is similar to json.Encoder.SetEscapeHTML(false).
NoUTF8Coercion Disables the replacement of invalid bytes with the Unicode replacement rune in JSON strings.
AllowList Sets a whitelist that represents which fields are to be encoded when marshaling a Go struct.
DenyList Sets a blacklist that represents which fields are ignored during the marshaling of a Go struct.
NoCompact Disables the compaction of JSON output produced by MarshalJSON method, and json.RawMessage values.
NoNumberValidation Disables the validation of json.Number values.
WithContext Sets the context.Context to be passed to invocations of AppendJSONContext methods.

Take a look at the examples to see these options in action.

Benchmarks

If you'd like to run the benchmarks yourself, use the following command.

go get github.com/cespare/prettybench
go test -bench=. | prettybench

Results -short

These benchmarks were run 10x (statistics computed with benchstat) on a MacBook Pro 15", with the following specs:

OS:  macOS Mojave (10.14.6)
CPU: 2.6 GHz Intel Core i7
Mem: 16GB
Go:  go version go1.15 darwin/amd64
Tag: v0.7.1
Stats
name                    time/op
Simple/standard-8          662ns ± 1%
Simple/jsoniter-8          775ns ± 1%
Simple/segmentj-8          380ns ± 1%
Simple/jettison-8          472ns ± 1%
Complex/standard-8        13.8µs ± 1%
Complex/jsoniter-8        14.1µs ± 1%
Complex/segmentj-8        9.72µs ± 1%
Complex/jettison-8        6.86µs ± 1%
CodeMarshal/standard-8    7.25ms ± 0%
CodeMarshal/jsoniter-8    8.27ms ± 1%
CodeMarshal/segmentj-8    5.54ms ± 0%
CodeMarshal/jettison-8    6.02ms ± 0%
Map/standard-8            2.19µs ± 1%
Map/jsoniter-8            1.83µs ± 1%
Map/segmentj-8            1.92µs ± 0%
Map/jettison-8             904ns ± 1%
Map/jettison-nosort-8      600ns ± 1%

name speed Simple/standard-8 204MB/s ± 1% Simple/jsoniter-8 174MB/s ± 1% Simple/segmentj-8 355MB/s ± 2% Simple/jettison-8 286MB/s ± 1% Complex/standard-8 61.8MB/s ± 1% Complex/jsoniter-8 58.1MB/s ± 1% Complex/segmentj-8 88.5MB/s ± 1% Complex/jettison-8 124MB/s ± 1% CodeMarshal/standard-8 268MB/s ± 0% CodeMarshal/jsoniter-8 235MB/s ± 1% CodeMarshal/segmentj-8 350MB/s ± 0% CodeMarshal/jettison-8 322MB/s ± 0% Map/standard-8 38.9MB/s ± 1% Map/jsoniter-8 46.4MB/s ± 1% Map/segmentj-8 44.3MB/s ± 0% Map/jettison-8 94.0MB/s ± 1% Map/jettison-nosort-8 142MB/s ± 1%

name alloc/op Simple/standard-8 144B ± 0% Simple/jsoniter-8 152B ± 0% Simple/segmentj-8 144B ± 0% Simple/jettison-8 144B ± 0% Complex/standard-8 4.76kB ± 0% Complex/jsoniter-8 4.65kB ± 0% Complex/segmentj-8 3.25kB ± 0% Complex/jettison-8 1.38kB ± 0% CodeMarshal/standard-8 1.95MB ± 1% CodeMarshal/jsoniter-8 1.99MB ± 2% CodeMarshal/segmentj-8 1.97MB ± 2% CodeMarshal/jettison-8 1.97MB ± 2% Map/standard-8 848B ± 0% Map/jsoniter-8 925B ± 0% Map/segmentj-8 592B ± 0% Map/jettison-8 96.0B ± 0% Map/jettison-nosort-8 160B ± 0%

name allocs/op Simple/standard-8 1.00 ± 0% Simple/jsoniter-8 2.00 ± 0% Simple/segmentj-8 1.00 ± 0% Simple/jettison-8 1.00 ± 0% Complex/standard-8 96.0 ± 0% Complex/jsoniter-8 86.0 ± 0% Complex/segmentj-8 64.0 ± 0% Complex/jettison-8 15.0 ± 0% CodeMarshal/standard-8 1.00 ± 0% CodeMarshal/jsoniter-8 2.00 ± 0% CodeMarshal/segmentj-8 1.00 ± 0% CodeMarshal/jettison-8 1.00 ± 0% Map/standard-8 19.0 ± 0% Map/jsoniter-8 15.0 ± 0% Map/segmentj-8 18.0 ± 0% Map/jettison-8 1.00 ± 0% Map/jettison-nosort-8 2.00 ± 0%

Simple [source]

Basic payload with fields of type string, int and bool.

Simple Benchmark Graph

Complex [source]

Large payload with a variety of composite Go types, such as struct, map, interface, multi-dimensions array and slice, with pointer and non-pointer value types.

Please note that this test is somewhat positively influenced by the performances of map marshaling.

Complex Benchmark Graph

CodeMarshal [source]

Borrowed from the encoding/json tests. See testdata/code.json.gz.

CodeMarshal Benchmark Graph

Map [source]

Simple map[string]int with 6 keys.

Map Graph

Credits

This library and its design has been inspired by the work of others at @bet365 and @segmentio. See the following projects for reference:

License

Jettison is licensed under the MIT license. See the LICENSE file.

This package also uses some portions of code from the Go encoding/json package. The associated license can be found in LICENSE.golang.

Issues
  • fatal error: runtime: name offset out of range

    fatal error: runtime: name offset out of range

    I'm getting this amazing error on go version go1.18.1 linux/amd64:

    runtime: nameOff 0x1276120 out of range 0x1029000 - 0x17d770e
    fatal error: runtime: name offset out of range
    goroutine 57 [running]:
    runtime.throw({0x1317f5a?, 0xc0001aec20?})
            /usr/lib/go/src/runtime/panic.go:992 +0x71 fp=0xc00060ca70 sp=0xc00060ca40 pc=0x435751
    runtime.resolveNameOff(0x11c5e60?, 0x1276120)
            /usr/lib/go/src/runtime/type.go:198 +0x265 fp=0xc00060cac8 sp=0xc00060ca70 pc=0x45ba25
    reflect.resolveNameOff(0x12ccb80?, 0x179e620?)
            /usr/lib/go/src/runtime/runtime1.go:498 +0x19 fp=0xc00060cae8 sp=0xc00060cac8 pc=0x460ed9
    reflect.(*rtype).nameOff(...)
            /usr/lib/go/src/reflect/type.go:729
    reflect.(*rtype).String(0x179e620)
            /usr/lib/go/src/reflect/type.go:799 +0x25 fp=0xc00060cb08 sp=0xc00060cae8 pc=0x4af745
    reflect.(*rtype).ptrTo(0x179e620)
            /usr/lib/go/src/reflect/type.go:1456 +0x65 fp=0xc00060cb98 sp=0xc00060cb08 pc=0x4b29e5
    reflect.PointerTo(...)
            /usr/lib/go/src/reflect/type.go:1442
    reflect.PtrTo(...)
            /usr/lib/go/src/reflect/type.go:1437
    github.com/wI2L/jettison.newMarshalerTypeInstr({0x17b0fe0, 0x179e620}, 0x0)
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:139 +0x58 fp=0xc00060cbd0 sp=0xc00060cb98 pc=0x9a2638
    github.com/wI2L/jettison.newInstruction({0x17b0fe0?, 0x179e620}, 0x20?, 0xe6?)
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:94 +0x52 fp=0xc00060cc08 sp=0xc00060cbd0 pc=0x9a21f2
    github.com/wI2L/jettison.cachedInstr({0x17b0fe0?, 0x179e620})
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:45 +0x85 fp=0xc00060cc40 sp=0xc00060cc08 pc=0x9a1f85
    github.com/wI2L/jettison.encodeInterface(0xc000022d00?, {0xc00037d000, 0xf, 0x1000}, {{0x17a6490, 0xc000040068}, {0x131a373, 0x23}, 0x5, 0xb1, ...})
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/encode.go:70 +0x87 fp=0xc00060ccd0 sp=0xc00060cc40 pc=0x99bec7
    github.com/wI2L/jettison.encodeStruct(0xc0001e50e0, {0xc00037d000?, 0x99b885?, 0x2021b00?}, {{0x17a6490, 0xc000040068}, {0x131a373, 0x23}, 0x5, 0xb1, ...}, ...)
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/encode.go:244 +0x4f0 fp=0xc00060cdf0 sp=0xc00060ccd0 pc=0x99d1b0
    github.com/wI2L/jettison.newStructFieldsInstr.func2(0x1346e501a90b46?, {0xc00037d000?, 0x7f2645981538?, 0x40?}, {{0x17a6490, 0xc000040068}, {0x131a373, 0x23}, 0x5, 0xb1, ...})
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:319 +0x65 fp=0xc00060ce78 sp=0xc00060cdf0 pc=0x9a3a25
    github.com/wI2L/jettison.marshalJSON({0x12a17a0?, 0xc0001e50e0?}, {{0x17a6490, 0xc000040068}, {0x131a373, 0x23}, 0x5, 0xb1, 0x0, 0x0})
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/json.go:167 +0xd9 fp=0xc00060cf40 sp=0xc00060ce78 pc=0x9a5499
    github.com/wI2L/jettison.MarshalOpts({0x12a17a0, 0xc0001e50e0}, {0xc00060d028, 0x4, 0xc0003cbc00?})
            /home/fiatjaf/comp/go/pkg/mod/github.com/w!i2!l/[email protected]/json.go:142 +0x1a9 fp=0xc00060d000 sp=0xc00060cf40 pc=0x9a5289
    github.com/lnbits/infinity/utils.JSONMarshal({0x12a17a0?, 0xc0001e50e0?})
            /home/fiatjaf/comp/infinity/utils/json.go:24 +0x6c fp=0xc00060d058 sp=0xc00060d000 pc=0x9ad2cc
    github.com/lnbits/infinity/api/apiutils.SendJSON({0x17a57a8, 0xc00002e2a0}, {0x12a17a0?, 0xc0001e50e0?})
            /home/fiatjaf/comp/infinity/api/apiutils/jsonresponse.go:10 +0x33 fp=0xc00060d088 sp=0xc00060d058 pc=0xb7c733
    github.com/lnbits/infinity/api.LnurlScan({0x17a57a8, 0xc00002e2a0}, 0xc0005ecb00)
            /home/fiatjaf/comp/infinity/api/wallet.go:347 +0x786 fp=0xc00060d5c8 sp=0xc00060d088 pc=0xf14ba6
    net/http.HandlerFunc.ServeHTTP(0xc0003a28f0?, {0x17a57a8?, 0xc00002e2a0?}, 0xc0005ecb00?)
            /usr/lib/go/src/net/http/server.go:2084 +0x2f fp=0xc00060d5f0 sp=0xc00060d5c8 pc=0x6d8e6f
    
    opened by fiatjaf 4
  • Timezone

    Timezone

    encode time.Time type can set timezone to encode to json string default is normal local in time.Time.loc if local string is invalid, use the default location

    opened by kanrin 4
  • Panic when marshaling maps in Go 1.18

    Panic when marshaling maps in Go 1.18

    Hi, I just updated to Go 1.18 and jettison (v0.7.3) started failing when marshaling maps. This code:

    package main
    
    import "github.com/wI2L/jettison"
    
    func main() {
    	jettison.Marshal(map[string]interface{}{
    		"test": 123,
    	})
    }
    

    will fail using Go 1.18 with this stacktrace:

    fatal error: unexpected signal during runtime execution
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x100 pc=0x460e05]
    
    goroutine 1 [running]:
    runtime.throw({0x4ca188?, 0xc00011c078?})
    	/home/flusflas/.gvm/gos/go1.18/src/runtime/panic.go:992 +0x71 fp=0xc00008da38 sp=0xc00008da08 pc=0x430bd1
    runtime.sigpanic()
    	/home/flusflas/.gvm/gos/go1.18/src/runtime/signal_unix.go:802 +0x3a9 fp=0xc00008da88 sp=0xc00008da38 pc=0x444789
    sync.(*Pool).Get(0x56b100)
    	/home/flusflas/.gvm/gos/go1.18/src/sync/pool.go:129 +0x25 fp=0xc00008dac0 sp=0xc00008da88 pc=0x460e05
    github.com/wI2L/jettison.encodeSortedMap(0x56b0c0, {0xc000138000, 0x1, 0x1000}, {{0x4e5730, 0xc00012c028}, {0x4c8fa0, 0x23}, 0x5, 0x0, ...}, ...)
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/encode.go:415 +0x7a fp=0xc00008dc00 sp=0xc00008dac0 pc=0x49a13a
    github.com/wI2L/jettison.encodeMap(0x2?, {0xc000138000, 0x0, 0x1000}, {{0x4e5730, 0xc00012c028}, {0x4c8fa0, 0x23}, 0x5, 0x0, ...}, ...)
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/encode.go:364 +0x337 fp=0xc00008dce0 sp=0xc00008dc00 pc=0x499cd7
    github.com/wI2L/jettison.newMapInstr.func1(0x56b000?, {0xc000138000?, 0xc00010c2b0?, 0xc000138000?}, {{0x4e5730, 0xc00012c028}, {0x4c8fa0, 0x23}, 0x5, 0x0, ...})
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:400 +0x72 fp=0xc00008dd70 sp=0xc00008dce0 pc=0x49ff52
    github.com/wI2L/jettison.wrapInlineInstr.func1(0xc00010e150, {0xc000138000?, 0x203000?, 0x0?}, {{0x4e5730, 0xc00012c028}, {0x4c8fa0, 0x23}, 0x5, 0x0, ...})
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/instruction.go:406 +0x65 fp=0xc00008dde0 sp=0xc00008dd70 pc=0x4a0165
    github.com/wI2L/jettison.marshalJSON({0x4b2a80?, 0xc00010e150?}, {{0x4e5730, 0xc00012c028}, {0x4c8fa0, 0x23}, 0x5, 0x0, 0x0, 0x0})
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/json.go:167 +0xd9 fp=0xc00008dea8 sp=0xc00008dde0 pc=0x4a0eb9
    github.com/wI2L/jettison.Marshal({0x4b2a80?, 0xc00010e150?})
    	/home/flusflas/go/pkg/mod/github.com/w!i2!l/[email protected]/json.go:115 +0xbf fp=0xc00008df48 sp=0xc00008dea8 pc=0x4a0d7f
    main.main()
    	/home/flusflas/main/main.go:6 +0x7a fp=0xc00008df80 sp=0xc00008df48 pc=0x4a601a
    

    I tried to look for any reported bug with pools in Go 1.18, but I didn't find anything, and I feel a little lost here.

    bug 
    opened by flusflas 3
  • API to handler decoder?

    API to handler decoder?

    Jsoniter is a drop in replacement for JSON, I thought you could post a benchmark there if you like to showcase more efficient JSON.

    https://github.com/kostya/benchmarks

    opened by proyb6 2
  • fix: encoding of a zero-value duration in string format

    fix: encoding of a zero-value duration in string format

    Instead of returning the constant byte slice containing the representation of the zero duration, appends its content to the destination slice.

    resolve #2

    bug 
    opened by wI2L 1
  • Omitting a value that marshals into `null` isn't possible?

    Omitting a value that marshals into `null` isn't possible?

    Hey,

    I've tried to replace encoding/json with jettison, since jettison has the omitnil tag.

    There are certain fields that I am using a custom type for. The idea behind the type is to allow a HTTP request to set a field to null via a PATCH request, but not automatically null all omitted fields. For that to work, null fields must not be see as empty when unmarshalling. However, when marshalling, these null-values have no worth and should be omitted. Is something like that possible?

    Let's say you had the following type:

    type Thing {
        A *NullableString
        B *NullableString
    }
    

    If you now had a resource where both A and B already had a value of Hello and you'd send the following request:

    {
        "A": null,
    

    Then field A should be nulled, while B will stay unchanged, since A was explicitly defined, but B was not. The easy solution would be to make two versions of all structs. One for requests and one for replies, however I think that isn't desirable, as it bloats the code and doesn't allow sharing code to work on these structs.

    Here's a small example. The second case will panic with json: error calling MarshalJSON for type *flows_service.NullableString: json: invalid value.

    package flows_service
    
    import (
    	"encoding/json"
    	"fmt"
    	"testing"
    
    	"github.com/wI2L/jettison"
    )
    
    type NullableString struct {
    	// Set indicates whether unmarshalled JSON contained the field.
    	Set bool
    	// This field is only relevant if Set is `true`
    	NonNull bool
    	// Val; Only relevant if NonNull and Set are `true`.
    	Val string
    }
    
    // MarshalJSON implements json.Marshaler.
    func (v *NullableString) MarshalJSON() ([]byte, error) {
    	if !v.Set || !v.NonNull {
    		return nil, nil
    	}
    
    	return json.Marshal(v.Val)
    }
    
    // UnmarshalJSON implements json.Unmarshaler.
    func (v *NullableString) UnmarshalJSON(data []byte) error {
    	// If this method was called, the value was set.
    	v.Set = true
    
    	if string(data) == "null" {
    		return nil
    	}
    
    	if err := json.Unmarshal(data, &v.Val); err != nil {
    		return err
    	}
    
    	v.NonNull = true
    	return nil
    }
    
    type Something struct {
    	Field *NullableString `json:"field,omitempty,omitnil"`
    }
    
    func TestMarshalling(t *testing.T) {
    	cases := []*Something{
    		{},
    		{
    			Field: &NullableString{},
    		},
    		{
    			Field: &NullableString{
    				Set: true,
    			},
    		},
    	}
    
    	for i, c := range cases {
    		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
    			data, err := jettison.Marshal(c)
    			if err != nil {
    				panic(err)
    			}
    			t.Log(string(data))
    		})
    	}
    }
    
    enhancement question 
    opened by Bios-Marcel 4
Releases(v0.7.4)
  • v0.7.4(Mar 21, 2022)

    Changelog

    • b72a5ea chore: update module version to 1.18 and fix build constraint lines
    • c439275 docs: update README and CHANGELOG for version 0.7.4
    • 683aeb1 ci: add go1.18 to test and benchmark matrixes
    • d25ddf1 chore: bump all dependencies
    • 44bcb2d fix: add reflect.mapiterinit link for go1.18

    Commits list: https://github.com/wI2L/jettison/compare/v0.7.3...v0.7.4

    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(Nov 3, 2021)

  • v0.7.2(Aug 31, 2021)

    Changelog

    78914e8 docs: update CHANGELOG for version 0.7.2 542a7fd chore: add goreleaser Github workflow 814551d docs: update benchmarks for go1.17 68edff5 chore: upgrade npm modules of charts generator tool 7912fae chore: update modules to latest version 05e978c fix: audit fix npm modules for charts tool 484f862 fix: move all CI/CD pipelines to GitHub actions 59f7e40 chore: update dependencies and benchmarks for go1.15 9314658 refactor: remove inlined functions in appendEscapedBytes 1ef26b4 refactor: minor performance improvements aa59591 chore: tidy go.mod file d517bbd docs: fix Github compare link of v0.7.1

    Source code(tar.gz)
    Source code(zip)
Fork of Go's standard library json encoder

A fork of the Go standard library's json encoder Why? https://github.com/golang/go/issues/6213 was proposed in 2013 but was never accepted. Difference

unchain.io 0 Nov 25, 2021
JSON Spanner - A Go package that provides a fast and simple way to filter or transform a json document

JSON SPANNER JSON Spanner is a Go package that provides a fast and simple way to

null 3 Jun 30, 2022
Go encoder and decoder for the NetBPM/PNM image formats. Compatible with Go's image packages.

gpnm This package implements an encoder and decoder for PNM image formats. It can be used with Go's image library. It covers all formats as defined by

null 0 Nov 26, 2021
COBS implementation in Go (Decoder) and C (Encoder & Decoder) with tests.

COBS Table of Contents About The project COBS Specification Getting Started 3.1. Prerequisites 3.2. Installation 3.3. Roadmap Contributing License Con

Thomas Höhenleitner 2 May 22, 2022
goi - The “Quite OK Image” format encoder / decoder for Go.

goi - The “Quite OK Image” format encoder / decoder for Go. QOI - The “Quite OK Image” - is losslessly image format that offering speedup both compres

neguse 14 Mar 3, 2022
Decoder/Encoder for GhostControls Gate Remotes

ghostcontrols Decoder/Encoder for GhostControls Gate Remotes GhostControls makes a variety of automatic gate operators, transmitters and keypads & rec

null 0 Jan 1, 2022
Package json implements encoding and decoding of JSON as defined in RFC 7159

Package json implements encoding and decoding of JSON as defined in RFC 7159. The mapping between JSON and Go values is described in the documentation for the Marshal and Unmarshal functions

High Performance, Kubernetes Native Object Storage 3 May 10, 2022
Json-go - CLI to convert JSON to go and vice versa

Json To Go Struct CLI Install Go version 1.17 go install github.com/samit22/js

Samit Ghimire 5 Mar 3, 2022
Fast JSON parser and validator for Go. No custom structs, no code generation, no reflection

fastjson - fast JSON parser and validator for Go Features Fast. As usual, up to 15x faster than the standard encoding/json. See benchmarks. Parses arb

Aliaksandr Valialkin 1.6k Jun 21, 2022
Kazaam was created with the goal of supporting easy and fast transformations of JSON data with Golang

kazaam Description Kazaam was created with the goal of supporting easy and fast transformations of JSON data with Golang. This functionality provides

Qntfy 205 Sep 17, 2021
Get JSON values quickly - JSON parser for Go

get json values quickly GJSON is a Go package that provides a fast and simple way to get values from a json document. It has features such as one line

Josh Baker 10.5k Jun 30, 2022
JSON diff library for Go based on RFC6902 (JSON Patch)

jsondiff jsondiff is a Go package for computing the diff between two JSON documents as a series of RFC6902 (JSON Patch) operations, which is particula

William Poussier 172 Jun 23, 2022
Fast JSON serializer for golang.

easyjson Package easyjson provides a fast and easy way to marshal/unmarshal Go structs to/from JSON without the use of reflection. In performance test

Free and open source software developed at Mail.Ru 3.8k Jun 22, 2022
Fast Color JSON Marshaller + Pretty Printer for Golang

ColorJSON: The Fast Color JSON Marshaller for Go What is this? This package is based heavily on hokaccha/go-prettyjson but has some noticible differen

Tyler Brock 110 Jun 16, 2022
A fast json parser for go

rjson rjson is a json parser that relies on Ragel-generated state machines for most parsing. rjson's api is minimal and focussed on efficient parsing.

WillAbides 47 Jun 15, 2022
A blazingly fast JSON serializing & deserializing library

Sonic A blazingly fast JSON serializing & deserializing library, accelerated by JIT(just-in-time compiling) and SIMD(single-instruction-multi-data). B

Bytedance Inc. 3k Jun 24, 2022
Fast json for go. Lightweight fork of jsoniter.

jx Fast json for go. Lightweight fork of jsoniter. Features Reduced scope (no reflection or encoding/json adapter) Fuzzing, improved test coverage Dra

ogen 61 Jun 25, 2022
/ˈdʏf/ - diff tool for YAML files, and sometimes JSON

dyff is inspired by the way the old BOSH v1 deployment output reported changes from one version to another by only showing the parts of a YAML file that change.

null 638 Jun 23, 2022
HuJSON: JSON for Humans (comments and trailing commas)

HuJSON - Human JSON The HuJSON decoder is a JSON decoder that also allows comments, both /* ... */ and // to end of line trailing commas on arrays and

Tailscale 394 Jun 28, 2022