Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace bytes.Buffer with strings.Builder #97552

Merged
merged 2 commits into from Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 23 additions & 17 deletions staging/src/k8s.io/apimachinery/pkg/labels/selector.go
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package labels

import (
"bytes"
"fmt"
"sort"
"strconv"
Expand Down Expand Up @@ -274,48 +273,55 @@ func (s internalSelector) Empty() bool {
// Requirement. If called on an invalid Requirement, an error is
// returned. See NewRequirement for creating a valid Requirement.
func (r *Requirement) String() string {
var buffer bytes.Buffer
var sb strings.Builder
sb.Grow(
// length of r.key
len(r.key) +
// length of 'r.operator' + 2 spaces for the worst case ('in' and 'notin')
len(r.operator) + 2 +
// length of 'r.strValues' slice times. Heuristically 5 chars per word
+5*len(r.strValues))
if r.operator == selection.DoesNotExist {
buffer.WriteString("!")
sb.WriteString("!")
}
buffer.WriteString(r.key)
sb.WriteString(r.key)

switch r.operator {
case selection.Equals:
buffer.WriteString("=")
sb.WriteString("=")
case selection.DoubleEquals:
buffer.WriteString("==")
sb.WriteString("==")
case selection.NotEquals:
buffer.WriteString("!=")
sb.WriteString("!=")
case selection.In:
buffer.WriteString(" in ")
sb.WriteString(" in ")
case selection.NotIn:
buffer.WriteString(" notin ")
sb.WriteString(" notin ")
case selection.GreaterThan:
buffer.WriteString(">")
sb.WriteString(">")
case selection.LessThan:
buffer.WriteString("<")
sb.WriteString("<")
case selection.Exists, selection.DoesNotExist:
return buffer.String()
return sb.String()
}

switch r.operator {
case selection.In, selection.NotIn:
buffer.WriteString("(")
sb.WriteString("(")
}
if len(r.strValues) == 1 {
buffer.WriteString(r.strValues[0])
sb.WriteString(r.strValues[0])
} else { // only > 1 since == 0 prohibited by NewRequirement
// normalizes value order on output, without mutating the in-memory selector representation
// also avoids normalization when it is not required, and ensures we do not mutate shared data
buffer.WriteString(strings.Join(safeSort(r.strValues), ","))
sb.WriteString(strings.Join(safeSort(r.strValues), ","))
}

switch r.operator {
case selection.In, selection.NotIn:
buffer.WriteString(")")
sb.WriteString(")")
}
return buffer.String()
return sb.String()
}

// safeSort sorts input strings without modification
Expand Down
18 changes: 18 additions & 0 deletions staging/src/k8s.io/apimachinery/pkg/labels/selector_test.go
Expand Up @@ -738,3 +738,21 @@ func TestValidatedSelectorFromSet(t *testing.T) {
}
}
}

func BenchmarkRequirementString(b *testing.B) {
r := Requirement{
key: "environment",
operator: selection.NotIn,
strValues: []string{
"dev",
},
}

b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if r.String() != "environment notin (dev)" {
b.Errorf("Unexpected Requirement string")
}
}
}
2 changes: 1 addition & 1 deletion staging/src/k8s.io/apimachinery/pkg/util/net/http.go
Expand Up @@ -693,7 +693,7 @@ func parseQuotedString(quotedString string) (string, string, error) {
var remainder string
escaping := false
closedQuote := false
result := &bytes.Buffer{}
result := &strings.Builder{}
loop:
for i := 0; i < len(quotedString); i++ {
b := quotedString[i]
Expand Down
18 changes: 18 additions & 0 deletions staging/src/k8s.io/apimachinery/pkg/util/net/http_test.go
Expand Up @@ -1107,3 +1107,21 @@ func TestPingTimeoutSeconds(t *testing.T) {
}
reset()
}

func Benchmark_ParseQuotedString(b *testing.B) {
str := `"The quick brown" fox jumps over the lazy dog`
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
quoted, remainder, err := parseQuotedString(str)
if err != nil {
b.Errorf("Unexpected error %s", err)
}
if quoted != "The quick brown" {
b.Errorf("Unexpected quoted string %s", quoted)
}
if remainder != "fox jumps over the lazy dog" {
b.Errorf("Unexpected remainder string %s", quoted)
}
}
}