mirror of
https://github.com/prometheus/prometheus
synced 2024-12-27 00:53:12 +00:00
Provide custom marshalling for Point
Point has a non-standard marshalling, and is also where the vast majority of CPU time is spent so it is worth optimising.
This commit is contained in:
parent
f35fca1c3f
commit
cc39021b2b
@ -26,8 +26,9 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/common/route"
|
||||
"github.com/prometheus/tsdb"
|
||||
@ -820,3 +821,41 @@ func parseDuration(s string) (time.Duration, error) {
|
||||
}
|
||||
return 0, fmt.Errorf("cannot parse %q to a valid duration", s)
|
||||
}
|
||||
|
||||
func init() {
|
||||
jsoniter.RegisterTypeEncoderFunc("promql.Point", marshalPointJSON, marshalPointJSONIsEmpty)
|
||||
}
|
||||
|
||||
func marshalPointJSON(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||
p := *((*promql.Point)(ptr))
|
||||
stream.WriteArrayStart()
|
||||
// Write out the timestamp as a float divided by 1000.
|
||||
// This is ~3x faster than converting to a float.
|
||||
t := p.T
|
||||
if t < 0 {
|
||||
stream.WriteRaw(`-`)
|
||||
t = -t
|
||||
}
|
||||
stream.WriteInt64(t / 1000)
|
||||
fraction := t % 1000
|
||||
if fraction != 0 {
|
||||
stream.WriteRaw(`.`)
|
||||
if fraction < 100 {
|
||||
stream.WriteRaw(`0`)
|
||||
}
|
||||
if fraction < 10 {
|
||||
stream.WriteRaw(`0`)
|
||||
}
|
||||
stream.WriteInt64(fraction)
|
||||
}
|
||||
stream.WriteMore()
|
||||
stream.WriteRaw(`"`)
|
||||
stream.WriteFloat64(p.V)
|
||||
stream.WriteRaw(`"`)
|
||||
stream.WriteArrayEnd()
|
||||
|
||||
}
|
||||
|
||||
func marshalPointJSONIsEmpty(ptr unsafe.Pointer) bool {
|
||||
return false
|
||||
}
|
||||
|
@ -882,11 +882,11 @@ func TestRespond(t *testing.T) {
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 10},
|
||||
expected: `{"status":"success","data":[0.01,"20"]}`,
|
||||
expected: `{"status":"success","data":[0.010,"20"]}`,
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 100},
|
||||
expected: `{"status":"success","data":[0.1,"20"]}`,
|
||||
expected: `{"status":"success","data":[0.100,"20"]}`,
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 1001},
|
||||
@ -894,15 +894,15 @@ func TestRespond(t *testing.T) {
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 1010},
|
||||
expected: `{"status":"success","data":[1.01,"20"]}`,
|
||||
expected: `{"status":"success","data":[1.010,"20"]}`,
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 1100},
|
||||
expected: `{"status":"success","data":[1.1,"20"]}`,
|
||||
expected: `{"status":"success","data":[1.100,"20"]}`,
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: 12345678123456555},
|
||||
expected: `{"status":"success","data":[12345678123456.557,"20"]}`,
|
||||
expected: `{"status":"success","data":[12345678123456.555,"20"]}`,
|
||||
},
|
||||
{
|
||||
response: promql.Point{V: 20, T: -1},
|
||||
|
Loading…
Reference in New Issue
Block a user