golang 字符串截取的比较

普通的截取

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

可以看出速度是可以的 ,也没有内存的分配申请,但是中文会产生乱码

中问的截取[]rune

var 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.DecodeRuneInString

func 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 差不多的,但是要稍微慢点 还是原始的最快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a...Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值