Reduce allocations on Query's io.Stringer implementation
A query's String method is called multiple times per query. This commit ensures all calls to query.String share use of a strings.NewReplacer. This approximately halves the number of allocations for the benchmarked query.pull/6713/head
parent
0752ca8d29
commit
853a95e0b3
|
@ -19,6 +19,7 @@
|
||||||
- [#6655](https://github.com/influxdata/influxdb/issues/6655): Add HTTP(s) based subscriptions.
|
- [#6655](https://github.com/influxdata/influxdb/issues/6655): Add HTTP(s) based subscriptions.
|
||||||
- [#5906](https://github.com/influxdata/influxdb/issues/5906): Dynamically update the documentation link in the admin UI.
|
- [#5906](https://github.com/influxdata/influxdb/issues/5906): Dynamically update the documentation link in the admin UI.
|
||||||
- [#6686](https://github.com/influxdata/influxdb/pull/6686): Optimize timestamp run-length decoding
|
- [#6686](https://github.com/influxdata/influxdb/pull/6686): Optimize timestamp run-length decoding
|
||||||
|
- [#6713](https://github.com/influxdata/influxdb/pull/6713): Reduce allocations during query parsing.
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,14 @@ import (
|
||||||
"github.com/influxdata/influxdb/influxql"
|
"github.com/influxdata/influxdb/influxql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func BenchmarkQuery_String(b *testing.B) {
|
||||||
|
p := influxql.NewParser(strings.NewReader(`SELECT foo AS zoo, a AS b FROM bar WHERE value > 10 AND q = 'hello'`))
|
||||||
|
q, _ := p.ParseStatement()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = q.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure a value's data type can be retrieved.
|
// Ensure a value's data type can be retrieved.
|
||||||
func TestInspectDataType(t *testing.T) {
|
func TestInspectDataType(t *testing.T) {
|
||||||
for i, tt := range []struct {
|
for i, tt := range []struct {
|
||||||
|
|
|
@ -2680,15 +2680,18 @@ func (p *Parser) parseTokenMaybe(expected Token) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
qsReplacer = strings.NewReplacer("\n", `\n`, `\`, `\\`, `'`, `\'`)
|
||||||
|
qiReplacer = strings.NewReplacer("\n", `\n`, `\`, `\\`, `"`, `\"`)
|
||||||
|
)
|
||||||
|
|
||||||
// QuoteString returns a quoted string.
|
// QuoteString returns a quoted string.
|
||||||
func QuoteString(s string) string {
|
func QuoteString(s string) string {
|
||||||
return `'` + strings.NewReplacer("\n", `\n`, `\`, `\\`, `'`, `\'`).Replace(s) + `'`
|
return `'` + qsReplacer.Replace(s) + `'`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuoteIdent returns a quoted identifier from multiple bare identifiers.
|
// QuoteIdent returns a quoted identifier from multiple bare identifiers.
|
||||||
func QuoteIdent(segments ...string) string {
|
func QuoteIdent(segments ...string) string {
|
||||||
r := strings.NewReplacer("\n", `\n`, `\`, `\\`, `"`, `\"`)
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
for i, segment := range segments {
|
for i, segment := range segments {
|
||||||
needQuote := IdentNeedsQuotes(segment) ||
|
needQuote := IdentNeedsQuotes(segment) ||
|
||||||
|
@ -2698,7 +2701,7 @@ func QuoteIdent(segments ...string) string {
|
||||||
_ = buf.WriteByte('"')
|
_ = buf.WriteByte('"')
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = buf.WriteString(r.Replace(segment))
|
_, _ = buf.WriteString(qiReplacer.Replace(segment))
|
||||||
|
|
||||||
if needQuote {
|
if needQuote {
|
||||||
_ = buf.WriteByte('"')
|
_ = buf.WriteByte('"')
|
||||||
|
|
Loading…
Reference in New Issue