mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 13:44:05 -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"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -28,8 +29,14 @@ import (
|
|||
"github.com/prometheus/prometheus/util/strutil"
|
||||
)
|
||||
|
||||
var parserPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &parser{}
|
||||
},
|
||||
}
|
||||
|
||||
type parser struct {
|
||||
lex *Lexer
|
||||
lex Lexer
|
||||
|
||||
inject ItemType
|
||||
injecting bool
|
||||
|
@ -54,7 +61,7 @@ func (e *ParseErr) Error() string {
|
|||
// ParseExpr returns the expression parsed from the input.
|
||||
func ParseExpr(input string) (expr Expr, err error) {
|
||||
p := newParser(input)
|
||||
|
||||
defer parserPool.Put(p)
|
||||
defer p.recover(&err)
|
||||
|
||||
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
|
||||
func ParseMetric(input string) (m labels.Labels, err error) {
|
||||
p := newParser(input)
|
||||
defer parserPool.Put(p)
|
||||
defer p.recover(&err)
|
||||
|
||||
return p.parseGenerated(START_METRIC).(labels.Labels), nil
|
||||
|
@ -75,6 +83,7 @@ func ParseMetric(input string) (m labels.Labels, err error) {
|
|||
// label matchers.
|
||||
func ParseMetricSelector(input string) (m []*labels.Matcher, err error) {
|
||||
p := newParser(input)
|
||||
defer parserPool.Put(p)
|
||||
defer p.recover(&err)
|
||||
|
||||
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.
|
||||
func newParser(input string) *parser {
|
||||
p := &parser{
|
||||
lex: Lex(input),
|
||||
p := parserPool.Get().(*parser)
|
||||
|
||||
p.injecting = false
|
||||
|
||||
// Clear lexer struct before reusing.
|
||||
p.lex = Lexer{
|
||||
input: input,
|
||||
state: lexStatements,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
@ -112,6 +127,7 @@ func parseSeriesDesc(input string) (labels labels.Labels, values []sequenceValue
|
|||
p := newParser(input)
|
||||
p.lex.seriesDesc = true
|
||||
|
||||
defer parserPool.Put(p)
|
||||
defer p.recover(&err)
|
||||
|
||||
result := p.parseGenerated(START_SERIES_DESCRIPTION).(*seriesDescription)
|
||||
|
|
Loading…
Reference in a new issue