MCPcopy Index your code
hub / github.com/avpetkun/jessy-go

github.com/avpetkun/jessy-go @v1.3.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.2 ↗ · + Follow
504 symbols 1,227 edges 45 files 142 documented · 28% updated 14mo ago★ 73
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Jessy is a high-performance JSON library for Go, focused on speed and reduced memory usage. It's a drop-in replacement for encoding/json and doesn't have dependencies

Before diving into the details, let's start with some metrics

Table of fastest big map encoding for demonstration memory usage

ns/op allocation bytes allocation times
jessy ✅ 232381883 321 1
jessy-pretty ✅ 272061406 382 1
sonic 748173167 489671300 40
jettison 292332917 510 3
jsoniter 542650438 559997264 5500005
gojson 344189542 337964296 100038
encoding/json 517449250 95207116 2700004

Marshal in compatibility mode

marshal

Fastest encode big map of 100k medium structs

fast-encode

See all benchmarks

Philosophy

  • Use reflection only once during the initial type processing
  • Perform later processing using only direct unsafe memory access
  • Minimize actions, checks, and conditions during repeated traversals
  • During the initial type processing, create a unique encoder for each field and nested type/structure
  • Always consider memory usage and speed
  • Benchmark every change to ensure performance
  • Fight for every nanosecond

API

// This is just a small part of all the available functions

// Marshal with encoding/json compatibility
func Marshal(value any) ([]byte, error)
// Marshal with encoding/json compatibility and \t indents
func MarshalPretty(value any) ([]byte, error)
// Marshal with fair indents (will be extra allocations, recommend use Pretty)
func MarshalIndent(value any, prefix, indent string) ([]byte, error)

// Fastest marshal without compatibility (e.g. unsorted maps)
func MarshalFast(value any) ([]byte, error)
// Fastest marshal with \t indents
func MarshalPrettyFast(value any) ([]byte, error)

// Marshal with custom parameters
func MarshalFlags(value any, flags Flags) ([]byte, error)

// All next append functions perform the same marshal, but use the provided buffer to avoid allocations.
// Highly recommended to use!

// Append json with encoding/json compatibility
func Append(dst []byte, value any) ([]byte, error)
// Fastest append json without compatibility
func AppendFast(dst []byte, value any) ([]byte, error)
// Append json with custom parameters
func AppendFlags(dst []byte, value any, flags Flags) ([]byte, error)

// You can also pre-cache in advance (not required)
func MarshalPrecache(value any, flags Flags)
func MarshalPrecacheFor[T any](flags Flags)


// Usually encoding/json Unmarshal
func Unmarshal(data []byte, v any) error
// Fast encoding/json unmarshal without checks
func UnmarshalTrusted(data []byte, v any) error

More zeroalloc marshal

You can implement special JsonAppender/TextAppender interface for zeroalloc some structs

type JsonAppender interface {
    AppendJSON(dst []byte) (newDst []byte, err error)
}
type TextAppender interface {
    AppendText(dst []byte) (newDst []byte, err error)
}

Custom marshal encoder

No matter how much we want to marshal a structure without memory allocations, sometimes our structures contain types from other libraries that we can't change.

The current library provides a way to handle this!

type UnsafeEncoder func(dst []byte, value unsafe.Pointer) ([]byte, error)
type ValueEncoder[T any] func(dst []byte, value T) ([]byte, error)

func AddUnsafeEncoder[T any](encoder func(flags Flags) UnsafeEncoder)
func AddValueEncoder[T any](encoder func(flags Flags) ValueEncoder[T])

Using example

import "github.com/avpetkun/jessy-go"

type MyType [10]byte

jessy.AddValueEncoder(func(flags Flags) jessy.ValueEncoder[MyType] {
    return func(dst []byte, v MyType) ([]byte, error) {
        dst = append(dst, '"')
        dst = appendHex(dst, v[:])
        dst = append(dst, '"')
        return dst, nil
    }
})

Drop-in replacement

Replace

import (
    "encoding/json"
)
json.Marshal(data)

with

import (
    json "github.com/avpetkun/jessy-go"
)
json.Marshal(data)

Hash

You can get fnv hash by all struct values

import "github.com/avpetkun/jessy-go"

hash, err := jessy.Hash(struct{A int}{123})

Features

In addition to the mentioned benefits, the library also:

  • Can marshal complex numbers
  • Can marshal maps with any key type

TODO

  • Extend the philosophy to the Unmarshal process
  • Optimize memory usage for map keys sorting
  • Add more code comments

How to get

go get github.com/avpetkun/jessy-go

Contribution Welcomed !

Extension points exported contracts — how you extend this code

Unmarshaler (Interface)
Unmarshaler is the interface implemented by types that can unmarshal a JSON description of themselves. The input can be
std/decode.go
JsonAppender (Interface)
(no doc) [1 implementers]
json_types.go
UnsafeEncoder (FuncType)
(no doc)
marshal.go
IsZeroer (Interface)
(no doc) [1 implementers]
json_types.go
ValueEncoder (FuncType)
(no doc)
marshal.go

Core symbols most depended-on inside this repo

Marshal
called by 67
marshal.go
Has
called by 56
flags.go
Equal
called by 53
require/require.go
NoError
called by 48
require/require.go
Hash
called by 47
hash.go
Kind
called by 39
zgo/type.go
saveError
called by 29
std/decode.go
error
called by 27
std/scanner.go

Shape

Function 256
Method 123
Struct 91
TypeAlias 28
FuncType 3
Interface 3

Languages

Go100%

Modules by API surface

json_encode_test.go82 symbols
zgo/map_swiss.go47 symbols
std/scanner.go45 symbols
std/decode.go38 symbols
marshal_test.go36 symbols
hash.go33 symbols
marshal.go24 symbols
benchmarks/bench_struct.go19 symbols
encode_numbers.go17 symbols
marshal_encoder.go14 symbols
encode_any.go12 symbols
zgo/type.go10 symbols

For agents

$ claude mcp add jessy-go \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact