Skip to content

Commit

Permalink
opt: support NoCopyRawMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
liuq19 committed Nov 12, 2024
1 parent b1872c1 commit 3212218
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 21 deletions.
194 changes: 173 additions & 21 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@
package sonic

import (
`bytes`
`encoding`
`encoding/json`
`errors`
`fmt`
`image`
`math`
`math/big`
`math/rand`
`net`
`reflect`
`strconv`
`strings`
`testing`
`time`
`unsafe`

`github.com/bytedance/sonic/decoder`
`github.com/bytedance/sonic/internal/native/types`
`github.com/davecgh/go-spew/spew`
`github.com/stretchr/testify/assert`
"bytes"
"encoding"
"encoding/json"
"errors"
"fmt"
"image"
"math"
"math/big"
"math/rand"
"net"
"reflect"
"runtime"
"strconv"
"strings"
"testing"
"time"
"unsafe"

"github.com/bytedance/sonic/decoder"
"github.com/bytedance/sonic/internal/native/types"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/assert"
)

type T struct {
Expand Down Expand Up @@ -2815,3 +2816,154 @@ func TestUseNumber(t *testing.T) {
}
}
}


func BenchmarkDecoderRawMessage(b *testing.B) {
data := ` {
"coordinates": null,
"favorited": false,
"truncated": false,
"created_at": "Mon Sep 24 03:35:21 +0000 2012",
"id_str": "250075927172759552",
"entities": {
"urls": [
],
"hashtags": [
{
"text": "freebandnames",
"indices": [
20,
34
]
}
],
"user_mentions": [
]
},
"in_reply_to_user_id_str": null,
"contributors": null,
"text": "Aggressive Ponytail #freebandnames",
"metadata": {
"iso_language_code": "en",
"result_type": "recent"
},
"retweet_count": 0,
"in_reply_to_status_id_str": null,
"id": 250075927172759552,
"geo": null,
"retweeted": false,
"in_reply_to_user_id": null,
"place": null,
"user": {
"profile_sidebar_fill_color": "DDEEF6",
"profile_sidebar_border_color": "C0DEED",
"profile_background_tile": false,
"name": "Sean Cummings",
"profile_image_url": "https://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
"created_at": "Mon Apr 26 06:01:55 +0000 2010",
"location": "LA, CA",
"follow_request_sent": null,
"profile_link_color": "0084B4",
"is_translator": false,
"id_str": "137238150",
"entities": {
"url": {
"urls": [
{
"expanded_url": null,
"url": "",
"indices": [
0,
0
]
}
]
},
"description": {
"urls": [
]
}
},
"default_profile": true,
"contributors_enabled": false,
"favourites_count": 0,
"url": null,
"profile_image_url_https": "https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
"utc_offset": -28800,
"id": 137238150,
"profile_use_background_image": true,
"listed_count": 2,
"profile_text_color": "333333",
"lang": "en",
"followers_count": 70,
"protected": false,
"notifications": null,
"profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme1/bg.png",
"profile_background_color": "C0DEED",
"verified": false,
"geo_enabled": true,
"time_zone": "Pacific Time (US & Canada)",
"description": "Born 330 Live 310",
"default_profile_image": false,
"profile_background_image_url": "https://a0.twimg.com/images/themes/theme1/bg.png",
"statuses_count": 579,
"friends_count": 110,
"following": null,
"show_all_inline_media": false,
"screen_name": "sean_cummings"
},
"in_reply_to_screen_name": null,
"source": "<a href=\"//itunes.apple.com/us/app/twitter/id409789998?mt=12%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for Mac</a>",
"in_reply_to_status_id": null
}`

bench := func(b *testing.B, run func(b *testing.B) ) {
b.ResetTimer()
b.ReportAllocs()
b.SetBytes(int64(len(data)))
for i := 0; i < b.N; i++ {
run(b)
}
runtime.GC()
}

b.Run("StdRawMessage", func(b *testing.B) {
bench(b, func(b *testing.B) {
var obj map[string]json.RawMessage
dc := decoder.NewDecoder(data)
dc.SetOptions(decoder.OptionUseNumber)
if err := dc.Decode(&obj); err!= nil {
b.Fatal(err.Error())
}
_ = obj
})
})

b.Run("NocopyRawMessage", func(b *testing.B) {
bench(b, func(b *testing.B) {
var obj map[string]NoCopyRawMessage
dc := decoder.NewDecoder(data)
dc.SetOptions(decoder.OptionUseNumber)
if err := dc.Decode(&obj); err!= nil {
b.Fatal(err.Error())
}
_ = obj
})
})


b.Run("NocopyRawMessageWithoutValidation", func(b *testing.B) {
bench(b, func(b *testing.B) {
var obj map[string]NoCopyRawMessage
dc := decoder.NewDecoder(data)
dc.SetOptions(decoder.OptionNoValidateJSON | decoder.OptionUseNumber)
if err := dc.Decode(&obj); err!= nil {
b.Fatal(err.Error())
}
_ = obj
})
})
}
43 changes: 43 additions & 0 deletions rawmessage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package sonic

import (
"errors"
)

// NoCopyRawMessage is a NOCOPY raw encoded JSON value.
// It implements [Marshaler] and [Unmarshaler] and can
// be used to delay JSON decoding or precompute a JSON encoding.
type NoCopyRawMessage []byte

// MarshalJSON returns m as the JSON encoding of m.
func (m NoCopyRawMessage) MarshalJSON() ([]byte, error) {
if m == nil {
return []byte("null"), nil
}
return m, nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *NoCopyRawMessage) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("sonic.NoCopyRawMessage: UnmarshalJSON on nil pointer")
}
*m = data
return nil
}

0 comments on commit 3212218

Please sign in to comment.