Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

acrazing/cheapjson

Repository files navigation

A arbitrary JSON parser for golang.

  • Standalone: implement the parser independently for ECMA-404 The JSON Data Interchange Standard.
  • Fast: about two times faster than the package go-simplejson which use native encoding/json library.
  • Lightweight: only about 500 rows code for parser include UTF-16 pairs covert to UTF-8 bytes.

Install

go get github.com/acrazing/cheapjson

Usage Example

package main
import (
 "github.com/acrazing/cheapjson"
 "encoding/json"
)
func main() {
 // Unmarshal a bytes slice
 value, err := cheapjson.Unmarshal([]byte("{\"hello\":\"world\", \"int\":12345}"))
 if err != nil {
 panic(err)
 }
 // type check
 if !value.IsObject() {
 panic("parse error")
 }
 // get a child field
 str := value.Get("hello")
 
 // get as string
 println(str.String()) // world
 
 // get as int
 println(value.Get("int").Int()) // 12345
 
 // And any else you can do:
 _ = value.Float() // returns float64
 _ = value.Array() // returns []*Value
 _ = value.Object() // returns map[string]*Value
 
 // WARNING: any of the upon value extract operate
 // need to check the type at first as follow:
 if value.IsObject() {
 // value is a object, and then you can operate:
 _ = value.Object()
 }
 // And there are more type checks
 _ = value.IsObject()
 _ = value.IsArray()
 _ = value.IsNumber() // if is float or int, returns true
 _ = value.IsInt() // just check is int
 _ = value.IsTrue()
 _ = value.IsFalse()
 _ = value.IsBool()
 _ = value.IsNull()
 _ = value.IsString()
 
 // And you can manipulate a value
 value = cheapjson.NewValue()
 value.AsObject(nil) // set as a object
 _ = value.AddField("hello") // if a value is a object, you can call this, else will panic
 value.AsArray(nil) // set as a array
 elem := value.AddElement() // if a value is a array, yu can call this, else will panic
 elem.AsInt(12) // as a int
 elem.AsFloat(232)
 elem.AsBool(true)
 elem.AsNull()
 
 // And you can get a deep path by:
 field := elem.Get("hello", "world", "deep", "3")
 _ = field.Value()
 // Or set a deep path
 // The different between Get and Ensure is that the Get
 // just returns the exists field, if the path does not exist
 // will return nil, and it will covert the path to integer
 // if the node is an array, and the Ensure will force the
 // path to be an object, and if the target path does not exist
 // will auto generate it as a empty node.
 value.Ensure("hello", "world", "deep", "3").AsInt(3)
 
 // And you can dump a value to raw struct
 data := value.Value()
 // and this could be json marshal
 _, _ = json.Marshal(data)
}

Benchmark

See parser_test.go, compare with go-simplejson, which use the native encoding/json library to unmarshal a json. The result is:

  • NormalInput(small): about 1.6 times faster
  • BigInput: about 4.4 times faster
  • DeepInput: about 7 times faster
go test -bench=. -v ./parser_test.go
# 2017年07月22日 12:48:45 big input size: 92338772, normal input size: 763, deep input size: 33976002
# === RUN TestUnmarshal
# --- PASS: TestUnmarshal (0.00s)
# === RUN TestSimpleJson
# --- PASS: TestSimpleJson (1.62s)
# BenchmarkUnmarshalBigInput-4 5 358595392 ns/op
# BenchmarkSimpleJsonBigInput-4 1 1560047078 ns/op
# BenchmarkUnmarshalNormalInput-4 200000 5372 ns/op
# BenchmarkSimpleJsonNormalInput-4 200000 8593 ns/op
# BenchmarkUnmarshalDeepInput-4 30 42870590 ns/op
# BenchmarkSimpleJsonDeepInput-4 5 305351224 ns/op
# PASS
# ok command-line-arguments 18.314s

License

MIT

TODO

  • more unit test.
  • test the performance about make buffer before handle a string, (will walk the string twice).

About

A fast arbitrary JSON parser for golang

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /