goccy / go-json

Fast JSON encoder/decoder compatible with encoding/json for Go
MIT License
2.99k stars 148 forks source link

Next Optimization Plan #357

Open goccy opened 2 years ago

goccy commented 2 years ago

Here are some optimization ideas that I'm currently thinking about

1. Optimization for standard library's Marshal(JSON|Text) and Unmarshal(JSON|Text)

The standard library's Marshaler returns valid and (compacted) JSON, so we can omit validation and compaction process for specified types e.g.) time.Time net.IP big.Float Similarly, json.RawMessage can be optimized .

2. Using unsafe.Add since Go 1.17

Since we can use more optimized instructions by using unsafe.Add, It can be expected that the speed of the part where pointer calculation is performed will be increased.

3. Add unordered option for struct fields when encoding

By adding the unordered option, encoding of the same type can be processed at once, which improves the execution efficiency of the VM. In some cases, tail-recursive optimization can be used in recursive instructions and interface instructions.

4. Opcode's design with CPU cache in mind

Adjusting the size of the structure used at the time of encoding makes it easier to be placed in the CPU cache.

trim21 commented 2 years ago

suggesstion:

Just assert ptr to time.Time and call time.Time{}.AppendFormat(buf, time.RFC3339Nano) direcly for time.Time?

goccy commented 2 years ago

Just assert ptr to time.Time and call time.Time{}.AppendFormat(buf, time.RFC3339Nano) direcly for time.Time?

Thank you for the comment, I've seen this optimization done in other libraries. However, I don't think that the contents of MarshalJSON should be implemented as it is even in the standard library, so I think it is better to call MarshalJSON of time.Time and skip compact and validation.

trim21 commented 2 years ago

this also give us the ability to add new marshal option like WithTimeFormat