github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/configs/legacy_promql/bench_test.go (about)

     1  // Copyright 2015 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, softwar
     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 promql
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"strconv"
    20  	"strings"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/prometheus/prometheus/pkg/labels"
    25  )
    26  
    27  func BenchmarkRangeQuery(b *testing.B) {
    28  	storage := NewStorage(b)
    29  	defer storage.Close()
    30  	engine := NewEngine(nil, nil, 10, 100*time.Second)
    31  
    32  	metrics := []labels.Labels{}
    33  	metrics = append(metrics, labels.FromStrings("__name__", "a_one"))
    34  	metrics = append(metrics, labels.FromStrings("__name__", "b_one"))
    35  	for j := 0; j < 10; j++ {
    36  		metrics = append(metrics, labels.FromStrings("__name__", "h_one", "le", strconv.Itoa(j)))
    37  	}
    38  	metrics = append(metrics, labels.FromStrings("__name__", "h_one", "le", "+Inf"))
    39  
    40  	for i := 0; i < 10; i++ {
    41  		metrics = append(metrics, labels.FromStrings("__name__", "a_ten", "l", strconv.Itoa(i)))
    42  		metrics = append(metrics, labels.FromStrings("__name__", "b_ten", "l", strconv.Itoa(i)))
    43  		for j := 0; j < 10; j++ {
    44  			metrics = append(metrics, labels.FromStrings("__name__", "h_ten", "l", strconv.Itoa(i), "le", strconv.Itoa(j)))
    45  		}
    46  		metrics = append(metrics, labels.FromStrings("__name__", "h_ten", "l", strconv.Itoa(i), "le", "+Inf"))
    47  	}
    48  
    49  	for i := 0; i < 100; i++ {
    50  		metrics = append(metrics, labels.FromStrings("__name__", "a_hundred", "l", strconv.Itoa(i)))
    51  		metrics = append(metrics, labels.FromStrings("__name__", "b_hundred", "l", strconv.Itoa(i)))
    52  		for j := 0; j < 10; j++ {
    53  			metrics = append(metrics, labels.FromStrings("__name__", "h_hundred", "l", strconv.Itoa(i), "le", strconv.Itoa(j)))
    54  		}
    55  		metrics = append(metrics, labels.FromStrings("__name__", "h_hundred", "l", strconv.Itoa(i), "le", "+Inf"))
    56  	}
    57  	refs := make([]uint64, len(metrics))
    58  
    59  	// A day of data plus 10k steps.
    60  	numIntervals := 8640 + 10000
    61  
    62  	for s := 0; s < numIntervals; s++ {
    63  		a := storage.Appender(context.Background())
    64  		ts := int64(s * 10000) // 10s interval.
    65  		for i, metric := range metrics {
    66  			var err error
    67  			refs[i], err = a.Append(refs[i], metric, ts, float64(s))
    68  
    69  			if err != nil {
    70  				b.Fatal(err)
    71  			}
    72  		}
    73  		if err := a.Commit(); err != nil {
    74  			b.Fatal(err)
    75  		}
    76  	}
    77  
    78  	type benchCase struct {
    79  		expr  string
    80  		steps int
    81  	}
    82  	cases := []benchCase{
    83  		// Plain retrieval.
    84  		{
    85  			expr: "a_X",
    86  		},
    87  		// Simple rate.
    88  		{
    89  			expr: "rate(a_X[1m])",
    90  		},
    91  		{
    92  			expr:  "rate(a_X[1m])",
    93  			steps: 10000,
    94  		},
    95  		// Holt-Winters and long ranges.
    96  		{
    97  			expr: "holt_winters(a_X[1d], 0.3, 0.3)",
    98  		},
    99  		{
   100  			expr: "changes(a_X[1d])",
   101  		},
   102  		{
   103  			expr: "rate(a_X[1d])",
   104  		},
   105  		// Unary operators.
   106  		{
   107  			expr: "-a_X",
   108  		},
   109  		// Binary operators.
   110  		{
   111  			expr: "a_X - b_X",
   112  		},
   113  		{
   114  			expr:  "a_X - b_X",
   115  			steps: 10000,
   116  		},
   117  		{
   118  			expr: "a_X and b_X{l=~'.*[0-4]$'}",
   119  		},
   120  		{
   121  			expr: "a_X or b_X{l=~'.*[0-4]$'}",
   122  		},
   123  		{
   124  			expr: "a_X unless b_X{l=~'.*[0-4]$'}",
   125  		},
   126  		// Simple functions.
   127  		{
   128  			expr: "abs(a_X)",
   129  		},
   130  		{
   131  			expr: "label_replace(a_X, 'l2', '$1', 'l', '(.*)')",
   132  		},
   133  		{
   134  			expr: "label_join(a_X, 'l2', '-', 'l', 'l')",
   135  		},
   136  		// Simple aggregations.
   137  		{
   138  			expr: "sum(a_X)",
   139  		},
   140  		{
   141  			expr: "sum without (l)(h_X)",
   142  		},
   143  		{
   144  			expr: "sum without (le)(h_X)",
   145  		},
   146  		{
   147  			expr: "sum by (l)(h_X)",
   148  		},
   149  		{
   150  			expr: "sum by (le)(h_X)",
   151  		},
   152  		// Combinations.
   153  		{
   154  			expr: "rate(a_X[1m]) + rate(b_X[1m])",
   155  		},
   156  		{
   157  			expr: "sum without (l)(rate(a_X[1m]))",
   158  		},
   159  		{
   160  			expr: "sum without (l)(rate(a_X[1m])) / sum without (l)(rate(b_X[1m]))",
   161  		},
   162  		{
   163  			expr: "histogram_quantile(0.9, rate(h_X[5m]))",
   164  		},
   165  	}
   166  
   167  	// X in an expr will be replaced by different metric sizes.
   168  	tmp := []benchCase{}
   169  	for _, c := range cases {
   170  		if !strings.Contains(c.expr, "X") {
   171  			tmp = append(tmp, c)
   172  		} else {
   173  			tmp = append(tmp, benchCase{expr: strings.Replace(c.expr, "X", "one", -1), steps: c.steps})
   174  			tmp = append(tmp, benchCase{expr: strings.Replace(c.expr, "X", "ten", -1), steps: c.steps})
   175  			tmp = append(tmp, benchCase{expr: strings.Replace(c.expr, "X", "hundred", -1), steps: c.steps})
   176  		}
   177  	}
   178  	cases = tmp
   179  
   180  	// No step will be replaced by cases with the standard step.
   181  	tmp = []benchCase{}
   182  	for _, c := range cases {
   183  		if c.steps != 0 {
   184  			tmp = append(tmp, c)
   185  		} else {
   186  			tmp = append(tmp, benchCase{expr: c.expr, steps: 1})
   187  			tmp = append(tmp, benchCase{expr: c.expr, steps: 10})
   188  			tmp = append(tmp, benchCase{expr: c.expr, steps: 100})
   189  			tmp = append(tmp, benchCase{expr: c.expr, steps: 1000})
   190  		}
   191  	}
   192  	cases = tmp
   193  	for _, c := range cases {
   194  		name := fmt.Sprintf("expr=%s,steps=%d", c.expr, c.steps)
   195  		b.Run(name, func(b *testing.B) {
   196  			b.ReportAllocs()
   197  			for i := 0; i < b.N; i++ {
   198  				qry, err := engine.NewRangeQuery(
   199  					storage, c.expr,
   200  					time.Unix(int64((numIntervals-c.steps)*10), 0),
   201  					time.Unix(int64(numIntervals*10), 0), time.Second*10)
   202  				if err != nil {
   203  					b.Fatal(err)
   204  				}
   205  				res := qry.Exec(context.Background())
   206  				if res.Err != nil {
   207  					b.Fatal(res.Err)
   208  				}
   209  				qry.Close()
   210  			}
   211  		})
   212  	}
   213  }