mirror of
https://github.com/golang/go
synced 2024-11-18 06:14:46 -07:00
fmt: optimize string truncation
Count only the runes up to the requested precision to decide where to truncate a string. Change the loop within truncate to need fewer jumps. name old time/op new time/op delta SprintfTruncateString-2 188ns ± 3% 155ns ± 3% -17.43% (p=0.000 n=20+20) Change-Id: I17ca9fc0bb8bf7648599df48e4785251bbc31e99 Reviewed-on: https://go-review.googlesource.com/20098 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
2faf5bca2e
commit
83765d135f
@ -199,7 +199,9 @@ var fmtTests = []struct {
|
||||
{"%08q", "abc", `000"abc"`},
|
||||
{"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
|
||||
{"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
|
||||
{"%.0s", "日本語日本語", ""},
|
||||
{"%.5s", "日本語日本語", "日本語日本"},
|
||||
{"%.10s", "日本語日本語", "日本語日本語"},
|
||||
{"%.5s", []byte("日本語日本語"), "日本語日本"},
|
||||
{"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
|
||||
{"%.5x", "abcdefghijklmnopqrstuvwxyz", `6162636465`},
|
||||
@ -928,6 +930,14 @@ func BenchmarkSprintfString(b *testing.B) {
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSprintfTruncateString(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
Sprintf("%.3s", "日本語日本語日本語")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSprintfInt(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
|
@ -282,14 +282,13 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
|
||||
|
||||
// truncate truncates the string to the specified precision, if present.
|
||||
func (f *fmt) truncate(s string) string {
|
||||
if f.precPresent && f.prec < utf8.RuneCountInString(s) {
|
||||
if f.precPresent {
|
||||
n := f.prec
|
||||
for i := range s {
|
||||
if n == 0 {
|
||||
s = s[:i]
|
||||
break
|
||||
}
|
||||
n--
|
||||
if n < 0 {
|
||||
return s[:i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return s
|
||||
|
Loading…
Reference in New Issue
Block a user