diff --git a/varfmt/fmt.go b/varfmt/fmt.go index 62789f7..6655308 100644 --- a/varfmt/fmt.go +++ b/varfmt/fmt.go @@ -17,17 +17,18 @@ func Sprintf(format string, args ...any) string { // init output strings.Builder and num rune buffer // cant use strings.Builder for storing num since // builder can't clear its contents without reallocating - output, num := strings.Builder{}, make([]rune, 0, 1) + output, num := strings.Builder{}, make([]rune, 0, 2) // first alloc here // convert args slice to strArgs string slice - strArgs, maxLen := make([]string, len(args), cap(args)), 0 + strArgs, maxLen := make([]string, len(args), cap(args)), 0 // second alloc here for i, arg := range args { - strArgs[i] = fmt.Sprint(arg) + strArgs[i] = fmt.Sprint(arg) // third and other allocs happen here + // could be further optimized if len(strArgs[i]) > maxLen { maxLen = len(strArgs[i]) } } // allocate maximum possible length of the resulting string - output.Grow(len(format) + len(args)*maxLen) + output.Grow(len(format) + len(args)*maxLen) // third alloc here start, argIndex := 0, 0 // decode runes one by one for start < len(format) { @@ -46,7 +47,7 @@ func Sprintf(format string, args ...any) string { // append new rune if the number is bigger // than the current buffer if numLength >= len(num) { - num = append(num, r) + num = append(num, r) // further allocs happen here } else { num[numLength] = r }