@@ -23,12 +23,14 @@ import (
2323 "strings"
2424 "testing"
2525
26+ "github.com/google/go-cmp/cmp"
2627 "github.com/prometheus/common/expfmt"
2728 "github.com/prometheus/common/model"
2829 "github.com/stretchr/testify/require"
2930
3031 "github.com/prometheus/prometheus/model/exemplar"
3132 "github.com/prometheus/prometheus/model/labels"
33+ "github.com/prometheus/prometheus/util/testutil"
3234)
3335
3436// BenchmarkParse... set of benchmarks analyze efficiency of parsing various
@@ -138,32 +140,81 @@ func BenchmarkParseOpenMetricsNHCB(b *testing.B) {
138140 }
139141}
140142
141- func benchParse (b * testing.B , data []byte , parser string ) {
142- type newParser func ([]byte , * labels.SymbolTable ) Parser
143+ // BenchmarkParseOpenMetricsNHCB_OM1vs2 is for demo of the benefit for the complex
144+ // type format for OM2, assuming Prometheus stores NS and NHCB (and NH) going forward.
145+ // Format draft: https://github.com/prometheus/docs/pull/2679
146+ /*
147+ export bench=out && go test ./model/textparse/... \
148+ -run '^$' -bench '^BenchmarkParseOpenMetricsNHCB_OM1vs2' \
149+ -benchtime 2s -count 6 -cpu 2 -benchmem -timeout 999m \
150+ | tee ${bench}.txt
151+ */
152+ func BenchmarkParseOpenMetricsNHCB_OM1vs2 (b * testing.B ) {
153+ parseCases := []struct {
154+ parser string
155+ data []byte
156+ }{
157+ {
158+ parser : "omtext_with_nhcb" , // Measure NHCB over OM parser.
159+ data : readTestdataFile (b , "1histogram.om.txt" ),
160+ },
161+ {
162+ parser : "om2text_with_nhcb" , // https://github.com/prometheus/docs/pull/2679 with NHCB output.
163+ data : readTestdataFile (b , "1histogram.om2.txt" ),
164+ },
165+ }
166+
167+ // Before we go, test parsing works as expected.
168+ gotA := testParse (b , newParser (b , parseCases [0 ].parser )(parseCases [0 ].data , labels .NewSymbolTable ()))
169+ gotB := testParse (b , newParser (b , parseCases [1 ].parser )(parseCases [1 ].data , labels .NewSymbolTable ()))
170+ testutil .RequireEqualWithOptions (b , gotA , gotB , []cmp.Option {cmp .AllowUnexported (parsedEntry {})})
171+
172+ // For fun, OM2 parser should work with classic histogram too (TODO add separate tests).
173+ _ = testParse (b , newParser (b , parseCases [1 ].parser )(parseCases [0 ].data , labels .NewSymbolTable ()))
174+
175+ for _ , c := range parseCases {
176+ b .Run (fmt .Sprintf ("parser=%v" , c .parser ), func (b * testing.B ) {
177+ benchParse (b , c .data , c .parser )
178+ })
179+ }
180+ }
181+
182+ func newParser (t testing.TB , parser string ) func ([]byte , * labels.SymbolTable ) Parser {
183+ t .Helper ()
143184
144- var newParserFn newParser
145185 switch parser {
146186 case "promtext" :
147- newParserFn = func (b []byte , st * labels.SymbolTable ) Parser {
187+ return func (b []byte , st * labels.SymbolTable ) Parser {
148188 return NewPromParser (b , st , false )
149189 }
150190 case "promproto" :
151- newParserFn = func (b []byte , st * labels.SymbolTable ) Parser {
191+ return func (b []byte , st * labels.SymbolTable ) Parser {
152192 return NewProtobufParser (b , true , false , false , st )
153193 }
154194 case "omtext" :
155- newParserFn = func (b []byte , st * labels.SymbolTable ) Parser {
195+ return func (b []byte , st * labels.SymbolTable ) Parser {
156196 return NewOpenMetricsParser (b , st , WithOMParserCTSeriesSkipped ())
157197 }
158198 case "omtext_with_nhcb" :
159- newParserFn = func (buf []byte , st * labels.SymbolTable ) Parser {
199+ return func (buf []byte , st * labels.SymbolTable ) Parser {
160200 p , err := New (buf , "application/openmetrics-text" , st , ParserOptions {ConvertClassicHistogramsToNHCB : true })
161- require .NoError (b , err )
201+ require .NoError (t , err )
162202 return p
163203 }
204+ case "om2text_with_nhcb" :
205+ return func (b []byte , st * labels.SymbolTable ) Parser {
206+ return NewOpenMetrics2Parser (b , st , func (options * openMetrics2ParserOptions ) {
207+ options .unrollComplexTypes = false
208+ })
209+ }
164210 default :
165- b .Fatal ("unknown parser" , parser )
211+ t .Fatal ("unknown parser" , parser )
166212 }
213+ return nil
214+ }
215+
216+ func benchParse (b * testing.B , data []byte , parser string ) {
217+ newParserFn := newParser (b , parser )
167218
168219 var (
169220 res labels.Labels
0 commit comments