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"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/common/route"
|
"github.com/prometheus/common/route"
|
||||||
"github.com/prometheus/tsdb"
|
"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)
|
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},
|
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},
|
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},
|
response: promql.Point{V: 20, T: 1001},
|
||||||
@ -894,15 +894,15 @@ func TestRespond(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
response: promql.Point{V: 20, T: 1010},
|
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},
|
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},
|
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},
|
response: promql.Point{V: 20, T: -1},
|
||||||
|
Loading…
Reference in New Issue
Block a user