Skip to content

Commit e1fb0af

Browse files
committed
feature: optimize fmt.Sprintf("%x" to strconv.FormatUint
using base 16
1 parent b873aa9 commit e1fb0af

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

analyzer/analyzer.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,11 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
283283
},
284284
}
285285

286-
case isBasicType(valueType, types.Uint8, types.Uint16, types.Uint32, types.Uint) && oneOf(verb, "%v", "%d") && n.intConv:
286+
case isBasicType(valueType, types.Uint8, types.Uint16, types.Uint32, types.Uint) && oneOf(verb, "%v", "%d", "%x") && n.intConv:
287+
base := []byte("), 10")
288+
if verb == "%x" {
289+
base = []byte("), 16")
290+
}
287291
d = &analysis.Diagnostic{
288292
Pos: call.Pos(),
289293
End: call.End(),
@@ -300,13 +304,17 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
300304
{
301305
Pos: value.End(),
302306
End: value.End(),
303-
NewText: []byte("), 10"),
307+
NewText: base,
304308
},
305309
},
306310
},
307311
},
308312
}
309-
case isBasicType(valueType, types.Uint64) && oneOf(verb, "%v", "%d"):
313+
case isBasicType(valueType, types.Uint64) && oneOf(verb, "%v", "%d", "%x"):
314+
base := []byte(", 10")
315+
if verb == "%x" {
316+
base = []byte(", 16")
317+
}
310318
d = &analysis.Diagnostic{
311319
Pos: call.Pos(),
312320
End: call.End(),
@@ -323,7 +331,7 @@ func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) {
323331
{
324332
Pos: value.End(),
325333
End: value.End(),
326-
NewText: []byte(", 10"),
334+
NewText: base,
327335
},
328336
},
329337
},

analyzer/replacements_bench_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,19 @@ func BenchmarkUintFormatting(b *testing.B) {
182182
b.ReportAllocs()
183183
})
184184
}
185+
186+
func BenchmarkUintHexFormatting(b *testing.B) {
187+
b.Run("fmt.Sprintf", func(b *testing.B) {
188+
for n := 0; n < b.N; n++ {
189+
_ = fmt.Sprintf("%x", uint64(math.MaxUint))
190+
}
191+
b.ReportAllocs()
192+
})
193+
194+
b.Run("strconv.FormatUint", func(b *testing.B) {
195+
for n := 0; n < b.N; n++ {
196+
_ = strconv.FormatUint(math.MaxUint, 16)
197+
}
198+
b.ReportAllocs()
199+
})
200+
}

analyzer/testdata/src/p/p.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ func positive() {
118118
fmt.Sprint(uint32(42)) // want "fmt.Sprint can be replaced with faster strconv.FormatUint"
119119
fmt.Sprintf("%d", ui64) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
120120
fmt.Sprintf("%v", ui64) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
121+
fmt.Sprintf("%x", ui64) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
122+
fmt.Sprintf("%x", uint(42)) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
121123
fmt.Sprint(ui64) // want "fmt.Sprint can be replaced with faster strconv.FormatUint"
122124
fmt.Sprintf("%d", uint64(42)) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
123125
fmt.Sprintf("%v", uint64(42)) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
@@ -386,7 +388,6 @@ func malformed() {
386388
fmt.Sprintf("%F", uint(42))
387389
fmt.Sprintf("%g", uint(42))
388390
fmt.Sprintf("%G", uint(42))
389-
fmt.Sprintf("%x", uint(42))
390391
fmt.Sprintf("%X", uint(42))
391392

392393
fmt.Sprintf("%d", 42.42)

analyzer/testdata/src/p/p.go.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ func positive() {
118118
strconv.FormatUint(uint64(uint32(42)), 10) // want "fmt.Sprint can be replaced with faster strconv.FormatUint"
119119
strconv.FormatUint(ui64, 10) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
120120
strconv.FormatUint(ui64, 10) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
121+
strconv.FormatUint(ui64, 16) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
122+
fmt.Sprintf("%x", uint(42)) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
121123
strconv.FormatUint(ui64, 10) // want "fmt.Sprint can be replaced with faster strconv.FormatUint"
122124
strconv.FormatUint(uint64(42), 10) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
123125
strconv.FormatUint(uint64(42), 10) // want "fmt.Sprintf can be replaced with faster strconv.FormatUint"
@@ -386,7 +388,6 @@ func malformed() {
386388
fmt.Sprintf("%F", uint(42))
387389
fmt.Sprintf("%g", uint(42))
388390
fmt.Sprintf("%G", uint(42))
389-
fmt.Sprintf("%x", uint(42))
390391
fmt.Sprintf("%X", uint(42))
391392

392393
fmt.Sprintf("%d", 42.42)

0 commit comments

Comments
 (0)