mirror of
https://github.com/ii64/sonic.git
synced 2026-06-21 00:46:43 +08:00
feat: add API MarshalString() (#197)
This commit is contained in:
parent
f087445eee
commit
c381c8b679
3 changed files with 15 additions and 7 deletions
|
|
@ -257,11 +257,12 @@ import (
|
|||
### Copy string
|
||||
When decoding **string values without any escaped characters**, sonic refers them from origin JSON buffer instead of mallocing a new buffer to copy. This helps a lot for CPU performance, but may leave the whole JSON buffer in memory as long as the decoded objects are being used. In practice, we found the extra memory introduced by referring JSON buffer is usually 20% ~ 80% of decoded objects. Once a application holds these objects for a long time (for example, cache the decoded objects for reusing), its inuse memory on server may go up. We provide option `decoder.CopyString()` for users to choose not to refer the JSON buffer, which may cause the decline of CPU performance in some degree.
|
||||
|
||||
### Pass string or []byte?
|
||||
For alignment to `encoding/json`, we provide API to pass `[]byte` as an argument, but the string-to-bytes copy is conducted at the same time considering safety, which may lose performance when origin JSON is huge. Therefore, you can use `UnmarshalString()` and `GetFromString()` to pass a string, as long as your origin data is a string or **nocopy-cast** is safe for your []byte. We also provides API `MarshalString()` for convenient **nocopy-cast** of encoded json []byte, which is safe since sonic's output bytes is always duplicated and unique.
|
||||
|
||||
### Accelerate `encoding.TextMarshaler`
|
||||
To ensure data security, sonic.Encoder quotes and escapes string values from `encoding.TextMarshaler` interfaces by default, which may degrade performance much if most of your data is in form of them. We provide `encoder.NoQuoteTextMarshaler` to skip these operations, which means you **MUST** ensure their output string escaped and quoted in accordance with [RFC8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
||||
|
||||
### Pass string or []byte?
|
||||
For alignment to `encoding/json`, we provide API to pass `[]byte` as an argument, but the string-to-bytes copy is conducted at the same time considering safety, which may lose performance when origin JSON is huge. Therefore, you can use `UnmarshalString` and `GetFromString` to pass a string, as long as your origin data is a string or **nocopy-cast** is safe for your []byte.
|
||||
|
||||
### Better performance for generic data
|
||||
In **fully-parsed** scenario, `Unmarshal()` performs better than `Get()`+`Node.Interface()`. But if you only have a part of schema for specific json, you can combine `Get()` and `Unmarshal()` together:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import (
|
|||
|
||||
func TestMain(m *testing.M) {
|
||||
go func () {
|
||||
if debugAsyncGC {
|
||||
if !debugAsyncGC {
|
||||
return
|
||||
}
|
||||
println("Begin GC looping...")
|
||||
|
|
@ -49,7 +49,7 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
|
||||
func TestGC(t *testing.T) {
|
||||
if !debugSyncGC {
|
||||
if debugSyncGC {
|
||||
return
|
||||
}
|
||||
var w interface{}
|
||||
|
|
|
|||
13
sonic.go
13
sonic.go
|
|
@ -25,17 +25,24 @@ import (
|
|||
`github.com/bytedance/sonic/encoder`
|
||||
`github.com/bytedance/sonic/option`
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
)
|
||||
|
||||
// Marshal returns the JSON encoding of v.
|
||||
// Marshal returns the JSON encoding bytes of v.
|
||||
func Marshal(val interface{}) ([]byte, error) {
|
||||
return encoder.Encode(val, 0)
|
||||
}
|
||||
|
||||
// MarshalString returns the JSON encoding string of v.
|
||||
func MarshalString(val interface{}) (string, error) {
|
||||
buf, err := encoder.Encode(val, 0)
|
||||
return rt.Mem2Str(buf), err
|
||||
}
|
||||
|
||||
// Unmarshal parses the JSON-encoded data and stores the result in the value
|
||||
// pointed to by v.
|
||||
// NOTICE: This API copies given buffer by default.
|
||||
// if you want to pass JSON more effecient, use UnmarshalString instead.
|
||||
// NOTICE: This API copies given buffer by default,
|
||||
// if you want to pass JSON more efficiently, use UnmarshalString instead.
|
||||
func Unmarshal(buf []byte, val interface{}) error {
|
||||
return UnmarshalString(string(buf), val)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue