1 回答

TA貢獻1998條經驗 獲得超6個贊
當性能和分配成為問題時,您應該運行基準測試。
首先讓我們修改您的函數以不打印而是返回結果:
func getLastRune(s string, c int) string {
j := len(s)
for i := 0; i < c && j > 0; i++ {
_, size := utf8.DecodeLastRuneInString(s[:j])
j -= size
}
return s[j:]
}
func getLastRune2(s string, c int) string {
r := []rune(s)
if c > len(r) {
c = len(r)
}
return string(r[len(r)-c:])
}
基準函數:
var s = "hogemogehogemogehogemoge世界世界世界a"
func BenchmarkGetLastRune(b *testing.B) {
for i := 0; i < b.N; i++ {
getLastRune(s, 3)
}
}
func BenchmarkGetLastRune2(b *testing.B) {
for i := 0; i < b.N; i++ {
getLastRune2(s, 3)
}
}
運行它們:
go test -bench . -benchmem
結果:
BenchmarkGetLastRune-4 30000000 36.9 ns/op 0 B/op 0 allocs/op
BenchmarkGetLastRune2-4 10000000 165 ns/op 0 B/op 0 allocs/op
getLastRune()快了 4 倍多。它們都沒有進行任何分配,但這是由于編譯器優化(將 a 轉換string為[]rune和返回通常需要分配)。
如果我們在禁用優化的情況下運行基準測試:
go test -gcflags '-N -l' -bench . -benchmem
結果:
BenchmarkGetLastRune-4 30000000 46.2 ns/op 0 B/op 0 allocs/op
BenchmarkGetLastRune2-4 10000000 197 ns/op 16 B/op 1 allocs/op
編譯器優化與否,getLastRune()是明顯的贏家。
- 1 回答
- 0 關注
- 225 瀏覽
添加回答
舉報