json-iterator / go Goto Github PK
View Code? Open in Web Editor NEWA high-performance 100% compatible drop-in replacement of "encoding/json"
Home Page: http://jsoniter.com/migrate-from-go-std.html
License: MIT License
A high-performance 100% compatible drop-in replacement of "encoding/json"
Home Page: http://jsoniter.com/migrate-from-go-std.html
License: MIT License
should be fixed
json_test.go:29: marshal expected:
{
> "-1538202063": 0.3634222946643717,
> "1223101607": 0.16867633434109314,
> "576443938": 0.020297602318735935
}
got:
{
> "576443938": 0.020297602318735935,
> "1223101607": 0.16867633434109314,
> "-1538202063": 0.3634222946643717
}
This is sort of tedious, but being exactly compatible has some value, right?
eg:
package main
import (
jsoniter "github.com/json-iterator/go"
)
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}
type TestObject struct {
Field []MyInterface
}
func main() {
obj := TestObject{}
b := []byte(`{"Field":["AAA"]}`)
jsoniter.Unmarshal(b, &obj)
}
https://github.com/json-iterator/go/blob/master/jsoniter.go#L159
应该是
case ' ', '\n', '\t', '\r':
package main
import (
"encoding/json"
"fmt"
"reflect"
jsoniter "github.com/json-iterator/go"
)
type Ttest map[string]string
func main() {
fn := func(name string, marshal func(interface{}) ([]byte, error), obj interface{}) []byte {
jb, err := marshal(obj)
if err != nil {
fmt.Printf("%s failed to marshal:\n error: %v\n", name, err)
return nil
}
return jb
}
var obj1 Ttest
jb1 := fn("json", json.Marshal, &obj1)
var obj2 Ttest
jb2 := fn("jsoniter", jsoniter.Marshal, &obj2)
if !reflect.DeepEqual(jb1, jb2) {
fmt.Printf("results differ:\n expected: %q\n got: %q\n", string(jb1), string(jb2))
}
}
yields:
results differ:
expected: "null"
got: "{}"
Changing map to slice also produces differences:
results differ:
expected: "null"
got: "[]"
float64 marshal loses data.
please see the sample :
`
import (
"log"
"encoding/json"
jsoniter "github.com/json-iterator/go"
)
type example struct {
Val float64 json:"val"
}
func main() {
v := example{0.000000099}
bytes, err := jsoniter.Marshal(v)
if err != nil {
log.Fatal(err)
}
log.Printf("jsoniter got: %s", string(bytes))
bytes, err = json.Marshal(v)
if err != nil {
log.Fatal(err)
}
log.Printf("json got: %s", string(bytes))
}
`
package main
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
)
func main() {
var b interface{}
json.Unmarshal([]byte(`{1 : "abc"}`), &b)
fmt.Println(b)
var c interface{}
jsoniter.Unmarshal([]byte(`{1 : "abc"}`), &c)
fmt.Println(c)
}
output:
<nil>
map[]
package main
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
)
type Ttest struct {
Map map[string]string
}
var jsonBytes = []byte(`
{
"Map":{
"k\"ey": "val"
}
}`)
func main() {
{
var obj Ttest
err := json.Unmarshal(jsonBytes, &obj)
if err != nil {
fmt.Printf("json failed to unmarshal:\n input: %s\n error: %v\n", string(jsonBytes), err)
}
}
{
var obj Ttest
err := jsoniter.Unmarshal(jsonBytes, &obj)
if err != nil {
fmt.Printf("jsoniter failed to unmarshal:\n input: %s\n error: %v\n", string(jsonBytes), err)
}
}
}
produces
jsoniter failed to unmarshal:
input:
{
"Map":{
"k\"ey": "val"
}
}
error: main.Ttest: Map: readObjectFieldAsBytes: expect : after object field, parsing 18 ...":{
"k\"... at
{
"Map":{
"k\"ey": "val"
}
}
json like this: {"id":1, "payload":{"account":"123","password":"456"}}
type AA struct{
ID int `json:"id"`,
Payload map[string]interface{} `json:"payload"`,
buf *bytes.Buffer,
}
if there is another field like buf, the jsoniter will not unmarshal correctly;when I delete the buf, It's OK, but in my program I need a struct with buf?
I have a battery of tests I have been working on to prove that JSON encoders are exactly compatible with Go's standard JSON. It doesn't pass against json-iterator yet (I filed the first bug just now), but I'd be happy to clean it up and contribute it here, if it is interesting to you to demonstrate that you're exactly compatible (and benchmark).
Before I do that work, I thought I would ask :)
// Only strings, floats, integers, and booleans can be quoted.
quoted := false
if opts.Contains("string") {
switch ft.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64,
reflect.String:
quoted = true
}
}
make the api compatible, including Marshal/Unmarshal spi
http://jsoniter.com/features.html
It should contain all features supported by Java. Excluding codegen (next step) and not applicable features (such as getter/setter/ctor).
streaming and non streaming code will be separated by compiler tags.
https://play.golang.org/p/h1oEbEfM7L
test("1e1") // 10 [Why not float!]
test("1.0e1") // 10 [Why not float!]
test(`"\"`) // [Why not error!]
jsoniter errors out with standard interface fields in struct where as encoding/json doesn't it.
sample:
package main
import (
"encoding/json"
"fmt"
"regexp"
jsoniter "github.com/json-iterator/go"
)
func fun1(input []byte) {
var tmp Example
err := jsoniter.Unmarshal(input, &tmp)
if err != nil {
fmt.Printf("JSONITER Error %v \n", err)
return
}
fmt.Printf("JSONITER Res %+v \n", tmp)
}
func fun2(input []byte) {
var tmp Example
err := json.Unmarshal(input, &tmp)
if err != nil {
fmt.Printf("JSON Error %v \n", err)
return
}
fmt.Printf("JSON Res %+v \n", tmp)
}
type Example struct {
Regexp string `json:"regexp"`
Compiled *regexp.Regexp `json:"compiled"`
}
func main() {
data := []byte(`{
"regexp": "mar.*"
}
`)
fun1(data)
fun2(data)
}
package main
import jsoniter "github.com/json-iterator/go"
func main() {
type _ResponseError struct {
Err string
Msg string
File string
Line int
}
type _JSONHTTPResponse struct {
Err string
Msg string
ErrStack []_ResponseError
Ret interface{}
}
resp := _JSONHTTPResponse{
Err: "BadJson",
Msg: "bad request json",
ErrStack: []_ResponseError{
_ResponseError{
Err: "BadJson",
Msg: "bad request json",
File: "xxx",
Line: 528,
},
_ResponseError{
Err: "Error",
Msg: "EOF",
File: "",
Line: 0,
},
},
Ret: interface{}(nil),
}
jsoniter.Marshal(resp)
}
golang 1.8
code
package main
import json "github.com/json-iterator/go"
import "fmt"
type Test struct {
Name string `json:"name"`
Data []map[string]string `json:"data"`
}
func main() {
sub := make(map[string]string)
sub["key"] = "value"
t := Test{Name: "test", Data: []map[string]string{sub}}
jsonStr, _ := json.MarshalToString(t)
fmt.Println(jsonStr)
panic
unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x8c34]
goroutine 1 [running]:
runtime.throw(0xe40ab, 0x5)
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/panic.go:566 +0x95 fp=0xc42003b8b0 sp=0xc42003b890
runtime.sigpanic()
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/sigpanic_unix.go:27 +0x288 fp=0xc42003b908 sp=0xc42003b8b0
runtime.mapiternext(0xc42006a060)
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/hashmap.go:731 +0xe4 fp=0xc42003b9b0 sp=0xc42003b908
runtime.mapiterinit(0xc7740, 0xc420028030, 0xc42006a060)
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/hashmap.go:679 +0x1c1 fp=0xc42003b9f0 sp=0xc42003b9b0
reflect.mapiterinit(0xc7740, 0xc420028030, 0x15)
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/hashmap.go:1029 +0x54 fp=0xc42003ba20 sp=0xc42003b9f0
reflect.Value.MapKeys(0xc7740, 0xc420028030, 0x15, 0xc420028030, 0x15, 0x0)
/usr/local/Cellar/go/1.7.4/libexec/src/reflect/value.go:1074 +0xc0 fp=0xc42003bac8 sp=0xc42003ba20
github.com/json-iterator/go.(*mapEncoder).encode(0xc42000e280, 0xc420028030, 0xc420010140)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect.go:241 +0xba fp=0xc42003bb78 sp=0xc42003bac8
github.com/json-iterator/go.(*sliceEncoder).encode(0xc4200164e0, 0xc420016400, 0xc420010140)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect_array.go:40 +0x89 fp=0xc42003bc00 sp=0xc42003bb78
github.com/json-iterator/go.(*structFieldEncoder).encode(0xc420016510, 0xc4200163f0, 0xc420010140)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect_object.go:1037 +0x97 fp=0xc42003bc80 sp=0xc42003bc00
github.com/json-iterator/go.(*structEncoder).encode(0xc4200122e0, 0xc4200163f0, 0xc420010140)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect_object.go:1067 +0x94 fp=0xc42003bcd0 sp=0xc42003bc80
github.com/json-iterator/go.WriteToStream(0xcc8a0, 0xc4200163f0, 0xc420010140, 0x15ac80, 0xc4200122e0)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect.go:35 +0xfa fp=0xc42003bd10 sp=0xc42003bcd0
github.com/json-iterator/go.(*structEncoder).encodeInterface(0xc4200122e0, 0xcc8a0, 0xc4200163f0, 0xc420010140)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect_object.go:1074 +0x55 fp=0xc42003bd48 sp=0xc42003bd10
github.com/json-iterator/go.(*Stream).WriteVal(0xc420010140, 0xcc8a0, 0xc4200163f0)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_reflect.go:344 +0xa8 fp=0xc42003bdb8 sp=0xc42003bd48
github.com/json-iterator/go.Marshal(0xcc8a0, 0xc4200163f0, 0xc42003be58, 0xc49b, 0xcc8a0, 0xc4200163f0, 0xc42003bf10)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_adapter.go:74 +0x144 fp=0xc42003be20 sp=0xc42003bdb8
github.com/json-iterator/go.MarshalToString(0xcc8a0, 0xc4200163f0, 0xc4200163f0, 0xcc8a0, 0xc4200163f0, 0x1)
/Users/maojun/GoWorkDir/src/github.com/json-iterator/go/feature_adapter.go:83 +0x39 fp=0xc42003be68 sp=0xc42003be20
main.main()
/Users/maojun/GoWorkDir/src/test.go:16 +0x1d1 fp=0xc42003bf48 sp=0xc42003be68
runtime.main()
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/proc.go:183 +0x1f4 fp=0xc42003bfa0 sp=0xc42003bf48
runtime.goexit()
/usr/local/Cellar/go/1.7.4/libexec/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42003bfa8 sp=0xc42003bfa0
exit status 2
should not complain in this case
mac 下的 Golang 1.8 环境
func BenchmarkHello2(b *testing.B) { rawString :=
{"id":0,"bidId":"bid01492692440885","impId":"imp0","taskId":"1024","bidPrice":80,"winPrice":0,"isWon":0,"createTime":1492692440885,"updateTime":null,"device":"","age":30,"gender":"","location":"[**, 山西, , ]","conType":"0","os":"iOS","osv":"","brand":"","geo":"","ip":"1.68.4.193","idfa":"","waxUserid":""}
var log bean.TaskBidLog hello.UnmarshalFromString(rawString, &log) b.Logf("%v\n", log.Age) }
用标准库里的就可以输出 30,但该库,一直没有成功。。。也没有见报错。。
when number exceed range, what will happen?
The jsoniter lib fails to marshall float64 in exponential form where as the unmarshal works fine.
Even though there are work arounds for this, its an api break wrt to the encoding/json in golang.
it's very frequency in use, i think it's very import to support it, I look the src code, but I found it's very complicate to fix it, need a lot of code.
RT.
The json tags are case sensitive in jsoniter where as encoding/json considers json tags as case insensitive.
This causes problem when decode json to interface, and then encode back to json
{"Info":{"InfoHash":"YWIlITn0T6UDgTqr8B8OLgC+mkw=","InfoHashstr":"6162252139F44FA503813AABF01F0E2E00BE9A4C","AnnounceList":null,"Length":7355754008,"PieceSize":8388608,"PieceNum":877},"InfoHashstr":"6162252139F44FA503813AABF01F0E2E00BE9A4C","SectionNum":40,"PieceNum":880,"PieceSize":16384,"Finished":false,"SparseSize":104857600,"Bit":[{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},{"Size":880,"EndIndex":-1,"EndMask":0,"Good":0,"Flush":false,"Bit":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}]}
上面这段json, 外层的Bit数组一共有40个,解析时,到第17个数组就结束了,后续就跟着报错啦.
在ReadArray中看到是 case 'n' 返回false, 结束数组解析.
it is way too complicated.
The un exported fields in struct gets it's value set during un marshal with jsoniter. One has to use json tags explicitly json:"-"
to prevent this. But with Go encoding/json lib it works based on whether the field is exported or not.
Sample
package main
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
)
func fun1(input []byte) {
var tmp Example
err := jsoniter.Unmarshal(input, &tmp)
if err != nil {
fmt.Printf("JSONITER Error %v \n", err)
return
}
fmt.Printf("JSONITER Res %+v \n", tmp)
}
func fun2(input []byte) {
var tmp Example
err := json.Unmarshal(input, &tmp)
if err != nil {
fmt.Printf("JSON Error %v \n", err)
return
}
fmt.Printf("JSON Res %+v \n", tmp)
}
type Example struct {
Exported string
unexported string
}
func main() {
data := []byte(`{
"Exported": "exportedVal",
"unexported": "unexportedVal"
}`)
fun1(data)
fun2(data)
}
type TorrentInfo struct {
InfoHash []byte json:"InfoHash"
InfoHashstr string json:"InfoHashstr"
AnnounceList []string json:"AnnounceList"
Length int64 json:"Length"
PieceSize int64 json:"PieceSize"
PieceNum int64 json:"PieceNum"
}
请问下,像InfoHash这种[]byte类型要如何解析,使用ReadStringAsBytes 不是我要的结果
Iterator.ReadInt() , 如果数据不是数字,现在会返回默认值0。无法判断是解析成功的结果,还是解析失败的结果。我觉得解析返回数据的方法都需要一个error,用来标记是否解析成功。
Hi,
I'd try encode map into json string but not found such sample or test code.
Since a critical bug of json.Marshal(map) in go version 1.7, I wanna try jsoniter.
Thanks.
this should make the marshal to bytes same as the standard library. Right now it is allocating more memory than standard library.
package json_test
import "testing"
import "github.com/json-iterator/go"
func TestJsoniter(t *testing.T) {
v := struct {
VV map[string]interface{}
Foo string
}{
VV: map[string]interface{}{
"foo": "bar",
},
Foo: "foo",
}
buf, err := jsoniter.Marshal(v)
if err != nil {
t.Error(err.Error())
return
}
t.Log(string(buf))
}
=== RUN TestJsoniter
unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x9a94]
goroutine 6 [running]:
runtime.throw(0x15f277, 0x5)
/usr/local/go/src/runtime/panic.go:566 +0x95 fp=0xc42004a9b8 sp=0xc42004a998
runtime.sigpanic()
/usr/local/go/src/runtime/sigpanic_unix.go:27 +0x288 fp=0xc42004aa10 sp=0xc42004a9b8
runtime.mapiternext(0xc420018420)
/usr/local/go/src/runtime/hashmap.go:731 +0xe4 fp=0xc42004aab8 sp=0xc42004aa10
runtime.mapiterinit(0x1375a0, 0xc420010440, 0xc420018420)
/usr/local/go/src/runtime/hashmap.go:679 +0x1c1 fp=0xc42004aaf8 sp=0xc42004aab8
reflect.mapiterinit(0x1375a0, 0xc420010440, 0x15)
/usr/local/go/src/runtime/hashmap.go:1029 +0x54 fp=0xc42004ab28 sp=0xc42004aaf8
reflect.Value.MapKeys(0x1375a0, 0xc420010440, 0x15, 0xc420010440, 0x15, 0x13200983e8)
/usr/local/go/src/reflect/value.go:1074 +0xc0 fp=0xc42004abd0 sp=0xc42004ab28
github.com/json-iterator/go.(*mapInterfaceEncoder).encode(0xc42000ab40, 0xc420010440, 0xc420014230)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect.go:255 +0xba fp=0xc42004ac88 sp=0xc42004abd0
github.com/json-iterator/go.(*structFieldEncoder).encode(0xc42000e750, 0xc420010440, 0xc420014230)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect_object.go:402 +0x97 fp=0xc42004ad08 sp=0xc42004ac88
github.com/json-iterator/go.(*structEncoder).encode(0xc420010460, 0xc420010440, 0xc420014230)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect_object.go:420 +0x54 fp=0xc42004ad50 sp=0xc42004ad08
github.com/json-iterator/go.WriteToStream(0x13dfa0, 0xc420010440, 0xc420014230, 0x1fd6e0, 0xc420010460)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect.go:34 +0xfa fp=0xc42004ad90 sp=0xc42004ad50
github.com/json-iterator/go.(*structEncoder).encodeInterface(0xc420010460, 0x13dfa0, 0xc420010440, 0xc420014230)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect_object.go:429 +0x55 fp=0xc42004adc8 sp=0xc42004ad90
github.com/json-iterator/go.(*Stream).WriteVal(0xc420014230, 0x13dfa0, 0xc420010440)
/Users/lyric/go/src/github.com/json-iterator/go/feature_reflect.go:312 +0xa8 fp=0xc42004ae38 sp=0xc42004adc8
github.com/json-iterator/go.Marshal(0x13dfa0, 0xc420010440, 0xc420010440, 0x13dfa0, 0xc420010440, 0x0, 0x0)
/Users/lyric/go/src/github.com/json-iterator/go/feature_adapter.go:74 +0x144 fp=0xc42004aea0 sp=0xc42004ae38
temp.com/json-sample_test.TestJsoniter(0xc42008e180)
/Users/lyric/go/src/temp.com/json-sample/map_test.go:17 +0x162 fp=0xc42004af78 sp=0xc42004aea0
testing.tRunner(0xc42008e180, 0x171588)
/usr/local/go/src/testing/testing.go:610 +0x81 fp=0xc42004afa0 sp=0xc42004af78
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42004afa8 sp=0xc42004afa0
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:646 +0x2ec
goroutine 1 [chan receive]:
testing.(*T).Run(0xc42008e0c0, 0x1604bd, 0xc, 0x171588, 0x58a01)
/usr/local/go/src/testing/testing.go:647 +0x316
testing.RunTests.func1(0xc42008e0c0)
/usr/local/go/src/testing/testing.go:793 +0x6d
testing.tRunner(0xc42008e0c0, 0xc420045e20)
/usr/local/go/src/testing/testing.go:610 +0x81
testing.RunTests(0x171070, 0x20c160, 0x2, 0x2, 0xe27b)
/usr/local/go/src/testing/testing.go:799 +0x319
testing.(*M).Run(0xc420045ee8, 0xc420045f00)
/usr/local/go/src/testing/testing.go:743 +0x85
main.main()
temp.com/json-sample/_test/_testmain.go:64 +0xc6
exit status 2
FAIL temp.com/json-sample 0.010s
Error: Tests failed.
b := `{"t": "\u002D\u002D\u002D", "l": "\u002d\u002d\u002d"}`
iter := jsoniter.ParseString(b)
i := iter.ReadAny()
fmt.Println(i.Get("t").ToString(), "|", i.Get("l").ToString())
// OutPut: | ---
解析时遇到 \u002D 这种字母大写的就解析不出来,小写就正常
This is good projects, But no more information for example, Could you write more example? And I can't find any document for your website about go version.
Starting to put a test framework together:
--- FAIL: Test_Roundtrip (0.02s)
json_test.go:29: marshal expected:
"M亐衇竆謱掲躃\u003c"
got:
"M亐衇竆謱掲躃<"
obj:
(test.T) (len=20) "M亐衇竆謱掲躃<"
json_test.go:29: marshal expected:
"5\u0026PīƓȝ黼Ŏ8r僇ńc蕼1舁5"
got:
"5&PīƓȝ黼Ŏ8r僇ńc蕼1舁5"
obj:
(test.T) (len=30) "5&PīƓȝ黼Ŏ8r僇ńc蕼1舁5"
json_test.go:29: marshal expected:
"]@Ʌzɴ\u0026ƾ地½ɏ6褐餗Ǝ"
got:
"]@Ʌzɴ&ƾ地½ɏ6褐餗Ǝ"
obj:
(test.T) (len=26) "]@Ʌzɴ&ƾ地½ɏ6褐餗Ǝ"
It looks like you're not handling unicode escapes as you should, if you want to be a drop-in replacement.
package main
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
)
func main() {
type Foo struct{}
type Bar struct {
A int
B int
}
v := struct {
Foo
Bar
}{
Foo: struct{}{},
Bar: Bar{
A: 1,
B: 2,
},
}
j, err := json.Marshal(v)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", j)
j, err = jsoniter.Marshal(v)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", j)
}
null can be valid input for string and struct
I am still not sure of the Marshal memory allocation figures, Guess you were referring to the stream.Buffer() change?
Do you happen to run it against the easyjson bench data?
My trials looks almost the same/worse for marshal -
Benchmark_EasyJson_Unmarshal_M-8 20000 67750 ns/op 9792 B/op 128 allocs/op
Benchmark_JSONITER_Unmarshal_M-8 30000 48937 ns/op 10096 B/op 178 allocs/op
Benchmark_EasyJson_Unmarshal_S-8 2000000 723 ns/op 128 B/op 3 allocs/op
Benchmark_JSONITER_Unmarshal_S-8 1000000 1061 ns/op 560 B/op 11 allocs/op
Benchmark_EasyJson_Marshal_M-8 100000 23034 ns/op 10378 B/op 10 allocs/op
Benchmark_JSONITER_Marshal_M-8 50000 30340 ns/op 33157 B/op 15 allocs/op
Benchmark_EasyJson_Marshal_L-8 2000 1135999 ns/op 462391 B/op 29 allocs/op
Benchmark_JSONITER_Marshal_L-8 1000 1410006 ns/op 1703766 B/op 468 allocs/op
tests are as below.
package benchmark
···
import (
"testing"
jsoniter "github.com/json-iterator/go"
"github.com/mailru/easyjson"
)
func Benchmark_EasyJson_Unmarshal_M(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var s LargeStruct
err := s.UnmarshalJSON(largeStructText)
if err != nil {
b.Error(err)
}
}
}
func Benchmark_JSONITER_Unmarshal_M(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var s LargeStruct
err := jsoniter.Unmarshal(largeStructText, &s)
if err != nil {
b.Error(err)
}
}
}
func Benchmark_EasyJson_Unmarshal_S(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var s Entities
err := s.UnmarshalJSON(smallStructText)
if err != nil {
b.Error(err)
}
}
}
func Benchmark_JSONITER_Unmarshal_S(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var s Entities
err := jsoniter.Unmarshal(smallStructText, &s)
if err != nil {
b.Error(err)
}
}
}
func Benchmark_EasyJson_Marshal_M(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := easyjson.Marshal(&largeStructData)
if err != nil {
b.Error(err)
}
//l = int64(len(data))
}
//b.SetBytes(l)
}
func Benchmark_JSONITER_Marshal_M(b *testing.B) {
ldata = largeStructDataJsoniter(largeStructData)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := jsoniter.Marshal(&ldata)
if err != nil {
b.Error(err)
}
//l = int64(len(data))
}
//b.SetBytes(l)
}
func Benchmark_EasyJson_Marshal_L(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := easyjson.Marshal(&xlStructData)
if err != nil {
b.Error(err)
}
//l = int64(len(data))
}
//b.SetBytes(l)
}
func Benchmark_JSONITER_Marshal_L(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := jsoniter.Marshal(&xldata)
if err != nil {
b.Error(err)
}
//l = int64(len(data))
}
//b.SetBytes(l)
}
···
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.