Skip to content

Commit eda7de1

Browse files
committed
Start to use json-iterator to improve marshalling of HistogramBucket
Signed-off-by: Jeanette Tan <[email protected]>
1 parent 01880dc commit eda7de1

File tree

4 files changed

+102
-20
lines changed

4 files changed

+102
-20
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.17
55
require (
66
github.com/go-kit/log v0.2.1
77
github.com/golang/protobuf v1.5.2
8+
github.com/json-iterator/go v1.1.12
89
github.com/julienschmidt/httprouter v1.3.0
910
github.com/matttproud/golang_protobuf_extensions v1.0.4
1011
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
@@ -23,6 +24,8 @@ require (
2324
github.com/cespare/xxhash/v2 v2.1.2 // indirect
2425
github.com/go-logfmt/logfmt v0.5.1 // indirect
2526
github.com/jpillora/backoff v1.0.0 // indirect
27+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
28+
github.com/modern-go/reflect2 v1.0.2 // indirect
2629
github.com/prometheus/procfs v0.8.0 // indirect
2730
github.com/stretchr/testify v1.8.0 // indirect
2831
golang.org/x/sys v0.3.0 // indirect

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
139139
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
140140
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
141141
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
142+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
142143
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
143144
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
144145
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
@@ -159,9 +160,11 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
159160
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
160161
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
161162
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
163+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
162164
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
163165
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
164166
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
167+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
165168
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
166169
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
167170
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=

model/value_histogram.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ import (
1818
"fmt"
1919
"strconv"
2020
"strings"
21+
"unsafe"
22+
23+
jsoniter "github.com/json-iterator/go"
2124
)
2225

26+
func init() {
27+
jsoniter.RegisterTypeEncoderFunc("model.HistogramBucket", marshalHistogramBucketJSON, marshalHistogramBucketJSONIsEmpty)
28+
}
29+
2330
type FloatString float64
2431

2532
func (v FloatString) String() string {
@@ -49,24 +56,14 @@ type HistogramBucket struct {
4956
Count FloatString
5057
}
5158

52-
func (s HistogramBucket) MarshalJSON() ([]byte, error) {
53-
b, err := json.Marshal(s.Boundaries)
54-
if err != nil {
55-
return nil, err
56-
}
57-
l, err := json.Marshal(s.Lower)
58-
if err != nil {
59-
return nil, err
60-
}
61-
u, err := json.Marshal(s.Upper)
62-
if err != nil {
63-
return nil, err
64-
}
65-
c, err := json.Marshal(s.Count)
66-
if err != nil {
67-
return nil, err
68-
}
69-
return []byte(fmt.Sprintf("[%s,%s,%s,%s]", b, l, u, c)), nil
59+
// marshalHistogramBucketJSON writes fmt.Sprintf("[%s,%s,%s,%s]", b.Boundaries, b.Lower, b.Upper, b.Count).
60+
func marshalHistogramBucketJSON(ptr unsafe.Pointer, stream *jsoniter.Stream) {
61+
b := *((*HistogramBucket)(ptr))
62+
MarshalHistogramBucket(b, stream)
63+
}
64+
65+
func marshalHistogramBucketJSONIsEmpty(ptr unsafe.Pointer) bool {
66+
return false
7067
}
7168

7269
func (s *HistogramBucket) UnmarshalJSON(buf []byte) error {
@@ -140,14 +137,15 @@ type SampleHistogramPair struct {
140137
}
141138

142139
func (s SampleHistogramPair) MarshalJSON() ([]byte, error) {
143-
t, err := json.Marshal(s.Timestamp)
140+
jsoni := jsoniter.ConfigCompatibleWithStandardLibrary
141+
t, err := jsoni.Marshal(s.Timestamp)
144142
if err != nil {
145143
return nil, err
146144
}
147145
if s.Histogram == nil {
148146
return nil, fmt.Errorf("histogram is nil")
149147
}
150-
v, err := json.Marshal(s.Histogram)
148+
v, err := jsoni.Marshal(s.Histogram)
151149
if err != nil {
152150
return nil, err
153151
}

model/value_marshal.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2013 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package model
15+
16+
import (
17+
"math"
18+
"strconv"
19+
20+
jsoniter "github.com/json-iterator/go"
21+
)
22+
23+
// from https://github.com/prometheus/prometheus/blob/main/util/jsonutil/marshal.go
24+
// MarshalTimestamp marshals a point timestamp using the passed jsoniter stream.
25+
func MarshalTimestamp(t int64, stream *jsoniter.Stream) {
26+
// Write out the timestamp as a float divided by 1000.
27+
// This is ~3x faster than converting to a float.
28+
if t < 0 {
29+
stream.WriteRaw(`-`)
30+
t = -t
31+
}
32+
stream.WriteInt64(t / 1000)
33+
fraction := t % 1000
34+
if fraction != 0 {
35+
stream.WriteRaw(`.`)
36+
if fraction < 100 {
37+
stream.WriteRaw(`0`)
38+
}
39+
if fraction < 10 {
40+
stream.WriteRaw(`0`)
41+
}
42+
stream.WriteInt64(fraction)
43+
}
44+
}
45+
46+
// adapted from https://github.com/prometheus/prometheus/blob/main/util/jsonutil/marshal.go
47+
// MarshalValue marshals a point value using the passed jsoniter stream.
48+
func MarshalValue(f FloatString, stream *jsoniter.Stream) {
49+
v := float64(f)
50+
stream.WriteRaw(`"`)
51+
// Taken from https://github.com/json-iterator/go/blob/master/stream_float.go#L71 as a workaround
52+
// to https://github.com/json-iterator/go/issues/365 (jsoniter, to follow json standard, doesn't allow inf/nan).
53+
buf := stream.Buffer()
54+
abs := math.Abs(v)
55+
fmt := byte('f')
56+
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
57+
if abs != 0 {
58+
if abs < 1e-6 || abs >= 1e21 {
59+
fmt = 'e'
60+
}
61+
}
62+
buf = strconv.AppendFloat(buf, v, fmt, -1, 64)
63+
stream.SetBuffer(buf)
64+
stream.WriteRaw(`"`)
65+
}
66+
67+
// adapted from https://github.com/prometheus/prometheus/blob/main/web/api/v1/api.go
68+
func MarshalHistogramBucket(b HistogramBucket, stream *jsoniter.Stream) {
69+
stream.WriteArrayStart()
70+
stream.WriteInt32(b.Boundaries)
71+
stream.WriteMore()
72+
MarshalValue(b.Lower, stream)
73+
stream.WriteMore()
74+
MarshalValue(b.Upper, stream)
75+
stream.WriteMore()
76+
MarshalValue(b.Count, stream)
77+
stream.WriteArrayEnd()
78+
}

0 commit comments

Comments
 (0)