use buffers for pathJoin, to re-use buffers. (#17960)

```
benchmark                        old ns/op     new ns/op     delta
BenchmarkPathJoin/PathJoin-8     79.6          55.3          -30.53%

benchmark                        old allocs     new allocs     delta
BenchmarkPathJoin/PathJoin-8     2              1              -50.00%

benchmark                        old bytes     new bytes     delta
BenchmarkPathJoin/PathJoin-8     48            24            -50.00%
```
This commit is contained in:
Harshavardhana
2023-08-31 17:58:48 -07:00
committed by GitHub
parent ea93643e6a
commit b1c1f02132
4 changed files with 63 additions and 21 deletions

View File

@@ -49,6 +49,7 @@ import (
"github.com/minio/minio/internal/logger"
"github.com/minio/pkg/trie"
"github.com/minio/pkg/wildcard"
"github.com/valyala/bytebufferpool"
"golang.org/x/exp/slices"
)
@@ -233,25 +234,25 @@ func pathsJoinPrefix(prefix string, elem ...string) (paths []string) {
// pathJoin - like path.Join() but retains trailing SlashSeparator of the last element
func pathJoin(elem ...string) string {
trailingSlash := ""
if len(elem) > 0 {
if hasSuffixByte(elem[len(elem)-1], SlashSeparatorChar) {
trailingSlash = SlashSeparator
}
}
return path.Join(elem...) + trailingSlash
sb := bytebufferpool.Get()
defer func() {
sb.Reset()
bytebufferpool.Put(sb)
}()
return pathJoinBuf(sb, elem...)
}
// pathJoinBuf - like path.Join() but retains trailing SlashSeparator of the last element.
// Provide a string builder to reduce allocation.
func pathJoinBuf(dst *bytes.Buffer, elem ...string) string {
func pathJoinBuf(dst *bytebufferpool.ByteBuffer, elem ...string) string {
trailingSlash := len(elem) > 0 && hasSuffixByte(elem[len(elem)-1], SlashSeparatorChar)
dst.Reset()
added := 0
for _, e := range elem {
if added > 0 || e != "" {
if added > 0 {
dst.WriteRune(SlashSeparatorChar)
dst.WriteByte(SlashSeparatorChar)
}
dst.WriteString(e)
added += len(e)
@@ -266,7 +267,7 @@ func pathJoinBuf(dst *bytes.Buffer, elem ...string) string {
return s
}
if trailingSlash {
dst.WriteRune(SlashSeparatorChar)
dst.WriteByte(SlashSeparatorChar)
}
return dst.String()
}