Skip to content

Commit

Permalink
reduce heap allocation (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktong authored Mar 11, 2024
1 parent 32760bb commit dc701cd
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 15 deletions.
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ var (
return strings.Split(f, ","), nil
}),
convert.WithHook[string, encoding.TextUnmarshaler](func(f string, t encoding.TextUnmarshaler) error {
return t.UnmarshalText([]byte(f)) //nolint:wrapcheck
return t.UnmarshalText(internal.String2ByteSlice(f)) //nolint:wrapcheck
}),
}
defaultConverter = convert.New(
Expand Down
2 changes: 1 addition & 1 deletion default.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@ var defaultConfig atomic.Pointer[Config] //nolint:gochecknoglobals
func init() { //nolint:gochecknoinits
var config Config
// Ignore error as env loader does not return error.
_ = config.Load(env.Env{})
_ = config.Load(env.New())
defaultConfig.Store(&config)
}
10 changes: 7 additions & 3 deletions internal/convert/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"reflect"
"strconv"
"strings"

"github.com/nil-go/konf/internal"
)

type Converter struct {
Expand Down Expand Up @@ -413,7 +415,8 @@ func (c Converter) convertSlice(name string, fromVal, toVal reflect.Value) error

return errors.Join(errs...)
case fromVal.Kind() == reflect.String && toVal.Type().Elem().Kind() == reflect.Uint8:
toVal.SetBytes([]byte(fromVal.String()))
s := fromVal.String()
toVal.SetBytes(internal.String2ByteSlice(s))
case fromVal.Kind() == reflect.Map:
// Empty maps turn into empty arrays
if fromVal.Len() == 0 {
Expand Down Expand Up @@ -454,9 +457,10 @@ func (c Converter) convertString(name string, fromVal, toVal reflect.Value) erro
case fromVal.Kind() == reflect.Array && fromVal.Type().Elem().Kind() == reflect.Uint8:
bytes := make([]uint8, fromVal.Len()) //nolint:makezero
reflect.Copy(reflect.ValueOf(bytes), fromVal)
toVal.SetString(string(bytes))
toVal.SetString(internal.ByteSlice2String(bytes))
case fromVal.Kind() == reflect.Slice && fromVal.Type().Elem().Kind() == reflect.Uint8:
toVal.SetString(string(fromVal.Bytes()))
bytes := fromVal.Bytes()
toVal.SetString(internal.ByteSlice2String(bytes))
default:
return fmt.Errorf( //nolint:goerr113
"'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
Expand Down
5 changes: 3 additions & 2 deletions internal/credential/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package credential
import (
"fmt"
"regexp"
"unsafe"

"github.com/nil-go/konf/internal"
)

func Blur(name string, value any) string {
Expand All @@ -19,7 +20,7 @@ func Blur(name string, value any) string {
case string:
formatted = v
case []byte:
formatted = unsafe.String(unsafe.SliceData(v), len(v))
formatted = internal.ByteSlice2String(v)
default:
formatted = fmt.Sprint(value)
}
Expand Down
22 changes: 22 additions & 0 deletions internal/string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2024 The konf authors
// Use of this source code is governed by a MIT license found in the LICENSE file.

package internal

import "unsafe"

func String2ByteSlice(str string) []byte {
if str == "" {
return nil
}

return unsafe.Slice(unsafe.StringData(str), len(str))
}

func ByteSlice2String(bs []byte) string {
if len(bs) == 0 {
return ""
}

return unsafe.String(unsafe.SliceData(bs), len(bs))
}
8 changes: 3 additions & 5 deletions provider/azappconfig/appconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,13 @@ func (p *clientProxy) load(ctx context.Context) (map[string]string, bool, error)
if p.client == nil {
if token, ok := p.credential.(*azidentity.DefaultAzureCredential); ok && reflect.ValueOf(*token).IsZero() {
var err error
credentialOptions := &azidentity.DefaultAzureCredentialOptions{}
if p.credential, err = azidentity.NewDefaultAzureCredential(credentialOptions); err != nil {
if p.credential, err = azidentity.NewDefaultAzureCredential(nil); err != nil {
return nil, false, fmt.Errorf("load default Azure credential: %w", err)
}
}

var err error
clientOptions := &azappconfig.ClientOptions{}
if p.client, err = azappconfig.NewClient(p.endpoint, p.credential, clientOptions); err != nil {
if p.client, err = azappconfig.NewClient(p.endpoint, p.credential, nil); err != nil {
return nil, false, fmt.Errorf("create Azure app configuration client: %w", err)
}
}
Expand All @@ -157,7 +155,7 @@ func (p *clientProxy) load(ctx context.Context) (map[string]string, bool, error)
if p.labelFilter != "" {
selector.LabelFilter = &p.labelFilter
}
pager := p.client.NewListSettingsPager(selector, &azappconfig.ListSettingsOptions{})
pager := p.client.NewListSettingsPager(selector, nil)

var (
values = make(map[string]string)
Expand Down
5 changes: 2 additions & 3 deletions provider/azblob/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,12 @@ func (p *clientProxy) load(ctx context.Context) ([]byte, bool, error) { //nolint
if p.client == nil {
if token, ok := p.credential.(*azidentity.DefaultAzureCredential); ok && reflect.ValueOf(*token).IsZero() {
var err error
credentialOptions := &azidentity.DefaultAzureCredentialOptions{}
if p.credential, err = azidentity.NewDefaultAzureCredential(credentialOptions); err != nil {
if p.credential, err = azidentity.NewDefaultAzureCredential(nil); err != nil {
return nil, false, fmt.Errorf("load default Azure credential: %w", err)
}
}

client, err := azblob.NewClient(p.endpoint, p.credential, &azblob.ClientOptions{})
client, err := azblob.NewClient(p.endpoint, p.credential, nil)
if err != nil {
return nil, false, fmt.Errorf("create Azure blob client: %w", err)
}
Expand Down

0 comments on commit dc701cd

Please sign in to comment.