普通的截取
var benchmarkStr = "此次进行的是中文的截取的性能测试情况"
func StrSplit(i,j int,str string)string{
return str[i:j]
}
func BenchmarkStrSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
StrSplit(3,10, benchmarkStr)
}
}
结果
goos: darwin
goarch: amd64
pkg: test/string/src
BenchmarkStrSplit-4 1000000000 0.579 ns/op 0 B/op 0 allocs/op
PASS
ok test/string/src 0.648s
go test -bench=StrSplit -benchmem 1.00s user 0.32s system 119% cpu 1.107 total
可以看出速度是可以的 ,也没有内存的分配申请,但是中文会产生乱码
中问的截取[]runevar benchmarkStr = "此次进行的是中文的截取的性能测试情况"
func SplitStrRunes(s string, length int) string {
if utf8.RuneCountInString(s) > length {
rs := []rune(s)
return string(rs[:length])
}
return s
}
func BenchmarkSubStrRunes(b *testing.B) {
for i := 0; i < b.N; i++ {
SplitStrRunes(benchmarkStr, 10)
}
}
goos: darwin
goarch: amd64
pkg: test/string/src
BenchmarkStrSplit-4 1000000000 0.573 ns/op 0 B/op 0 allocs/op
BenchmarkSubStrRunes-4 2704357 443 ns/op 48 B/op 1 allocs/op
PASS
ok test/string/src 2.288s
go test -bench=. -benchmem 2.63s user 0.22s system 110% cpu 2.569 total
时间相比传统的截取,发生了内存拷贝,并且时间很长
提升性能的utf8.DecodeRuneInStringfunc BenchmarkStrSplit(b *testing.B) {
for i := 0; i < b.N; i++ {
StrSplit(3,10, benchmarkStr)
}
}
func SubStrDecodeRuneInString(s string, length int) string {
var size, n int
for i := 0; i < length && n < len(s); i++ {
_, size = utf8.DecodeRuneInString(s[n:])
n += size
}
return s[:n]
}
结果
goos: darwin
goarch: amd64
pkg: test/string/src
BenchmarkStrSplit-4 1000000000 0.620 ns/op 0 B/op 0 allocs/op
BenchmarkSubStrDecodeRuneInString-4 18224007 61.1 ns/op 0 B/op 0 allocs/op
BenchmarkSubStrRunes-4 2541043 439 ns/op 48 B/op 1 allocs/op
PASS
ok test/string/src 3.470s
go test -bench=. -benchmem 3.83s user 0.52s system 101% cpu 4.298 total
结果和[]rune相比性能提升了很多,而且减少了内存分配的次数,但是和传统饮用还是有很大的差距
for range迭代字符,不是字节func SubStrRange(s string, length int) string {
var n, i int
for i = range s {
if n == length {
break
}
n++
}
return s[:i]
}
func BenchmarkSubStrRange(b *testing.B) {
for i := 0; i < b.N; i++ {
SubStrRange(benchmarkStr, 10)
}
}
结果
goos: darwin
goarch: amd64
pkg: test/string/src
BenchmarkStrSplit-4 1000000000 0.582 ns/op 0 B/op 0 allocs/op
BenchmarkSubStrDecodeRuneInString-4 19436258 61.8 ns/op 0 B/op 0 allocs/op
BenchmarkSubStrRunes-4 2709249 454 ns/op 48 B/op 1 allocs/op
BenchmarkSubStrRange-4 13656135 87.3 ns/op 0 B/op 0 allocs/op
PASS
ok test/string/src 4.877s
go test -bench=. -benchmem 5.23s user 0.58s system 101% cpu 5.733 total
多次结果发现 for _range 是和utf8.DecodeRuneInString 差不多的,但是要稍微慢点 还是原始的最快