mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-26 22:19:40 -08:00
PromQL: Use a sync.Pool for the generated parser structure (#6591)
* PromQL: Use a sync.Pool for the generated parser structure The generated PromQL parser allocates a struct about 4kb in size on every run. This puts a high load on the garbage collector. To reduce that load, a sync.Pool is used to recycle these structures. On small queries this makes parsing 2-3 times faster. Signed-off-by: Tobias Guggenmos <tguggenm@redhat.com>
This commit is contained in:
parent
863613300d
commit
6534ce843f
|
@ -19,6 +19,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -28,8 +29,14 @@ import (
|
||||||
"github.com/prometheus/prometheus/util/strutil"
|
"github.com/prometheus/prometheus/util/strutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var parserPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return &parser{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
type parser struct {
|
type parser struct {
|
||||||
lex *Lexer
|
lex Lexer
|
||||||
|
|
||||||
inject ItemType
|
inject ItemType
|
||||||
injecting bool
|
injecting bool
|
||||||
|
@ -54,7 +61,7 @@ func (e *ParseErr) Error() string {
|
||||||
// ParseExpr returns the expression parsed from the input.
|
// ParseExpr returns the expression parsed from the input.
|
||||||
func ParseExpr(input string) (expr Expr, err error) {
|
func ParseExpr(input string) (expr Expr, err error) {
|
||||||
p := newParser(input)
|
p := newParser(input)
|
||||||
|
defer parserPool.Put(p)
|
||||||
defer p.recover(&err)
|
defer p.recover(&err)
|
||||||
|
|
||||||
expr = p.parseGenerated(START_EXPRESSION).(Expr)
|
expr = p.parseGenerated(START_EXPRESSION).(Expr)
|
||||||
|
@ -66,6 +73,7 @@ func ParseExpr(input string) (expr Expr, err error) {
|
||||||
// ParseMetric parses the input into a metric
|
// ParseMetric parses the input into a metric
|
||||||
func ParseMetric(input string) (m labels.Labels, err error) {
|
func ParseMetric(input string) (m labels.Labels, err error) {
|
||||||
p := newParser(input)
|
p := newParser(input)
|
||||||
|
defer parserPool.Put(p)
|
||||||
defer p.recover(&err)
|
defer p.recover(&err)
|
||||||
|
|
||||||
return p.parseGenerated(START_METRIC).(labels.Labels), nil
|
return p.parseGenerated(START_METRIC).(labels.Labels), nil
|
||||||
|
@ -75,6 +83,7 @@ func ParseMetric(input string) (m labels.Labels, err error) {
|
||||||
// label matchers.
|
// label matchers.
|
||||||
func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
|
func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
|
||||||
p := newParser(input)
|
p := newParser(input)
|
||||||
|
defer parserPool.Put(p)
|
||||||
defer p.recover(&err)
|
defer p.recover(&err)
|
||||||
|
|
||||||
return p.parseGenerated(START_METRIC_SELECTOR).(*VectorSelector).LabelMatchers, nil
|
return p.parseGenerated(START_METRIC_SELECTOR).(*VectorSelector).LabelMatchers, nil
|
||||||
|
@ -82,8 +91,14 @@ func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
|
||||||
|
|
||||||
// newParser returns a new parser.
|
// newParser returns a new parser.
|
||||||
func newParser(input string) *parser {
|
func newParser(input string) *parser {
|
||||||
p := &parser{
|
p := parserPool.Get().(*parser)
|
||||||
lex: Lex(input),
|
|
||||||
|
p.injecting = false
|
||||||
|
|
||||||
|
// Clear lexer struct before reusing.
|
||||||
|
p.lex = Lexer{
|
||||||
|
input: input,
|
||||||
|
state: lexStatements,
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
@ -112,6 +127,7 @@ func parseSeriesDesc(input string) (labels labels.Labels, values []sequenceValue
|
||||||
p := newParser(input)
|
p := newParser(input)
|
||||||
p.lex.seriesDesc = true
|
p.lex.seriesDesc = true
|
||||||
|
|
||||||
|
defer parserPool.Put(p)
|
||||||
defer p.recover(&err)
|
defer p.recover(&err)
|
||||||
|
|
||||||
result := p.parseGenerated(START_SERIES_DESCRIPTION).(*seriesDescription)
|
result := p.parseGenerated(START_SERIES_DESCRIPTION).(*seriesDescription)
|
||||||
|
|
Loading…
Reference in a new issue