Closed thinkeridea closed 4 years ago
测试的代码片段在这里:
package test
import (
"testing"
"unicode/utf8"
"github.com/thinkeridea/go-extend/exbytes"
)
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
func ReverseRangeString(s string) string {
n := len(s)
buf := make([]byte, n)
var start, end int
for _, r := range s {
l := utf8.RuneLen(r)
n -= l
end = start + l
copy(buf[n:], s[start:end])
start = end
}
return exbytes.ToString(buf)
}
func ReverseUTF8DecodeRuneInString(s string) string {
n := len(s)
buf := make([]byte, n)
var start, size, end int
for i := 0; i < len(s[start:]); {
_, size = utf8.DecodeRuneInString(s[start:])
n -= size
end = start + size
copy(buf[n:], s[start:end])
start = end
}
return exbytes.ToString(buf)
}
func BenchmarkReverse(b *testing.B) {
s := "Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。为了方便搜索和识别,有时会将其称为Golang。"
for i := 0; i < b.N; i++ {
Reverse(s)
}
}
func BenchmarkReverseRangeString(b *testing.B) {
s := "Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。为了方便搜索和识别,有时会将其称为Golang。"
for i := 0; i < b.N; i++ {
ReverseRangeString(s)
}
}
func BenchmarkReverseUTF8DecodeRuneInString(b *testing.B) {
s := "Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。为了方便搜索和识别,有时会将其称为Golang。"
for i := 0; i < b.N; i++ {
ReverseUTF8DecodeRuneInString(s)
}
}
这里是测试结果:
goos: darwin
goarch: amd64
BenchmarkReverse-8 695608 1692 ns/op 480 B/op 2 allocs/op
BenchmarkReverseRangeString-8 1439391 823 ns/op 192 B/op 1 allocs/op
BenchmarkReverseUTF8DecodeRuneInString-8 1735574 692 ns/op 192 B/op 1 allocs/op
PASS
ok command-line-arguments 5.978s
这样的结果令我非常的吃惊,我暂时没有找到utf8获取指定字符的字节数方法,我只得到了逐个字符解析的方法,但这已经令我非常的吃惊,我想这样还有很大的改善空间
哇!你已经把它放入仓库了? XD good job good job!
@hollowaykeanho 这只是应用 utf8.DecodeRuneInString
调整了 exstrings.Reverse
的函数,我并没有把截断多字节字符串的方法放入到仓库中,暂时还不明确如何提供函数接口,但我有这个计划近期会实现这一目标。
该方法收集于官网 How to write Go code 中的一个代码片段,因曾经面试遇到这个面试题而留心。
近期回答 Go Forum 中关于 [SOLVED] String size of 20 character 中字符串长度截取使用
[]rune
类型与字符串类型转换,期望处理安全的unicode
字符。我对此方法提出了性能质疑,编写了基于
utf8.DecodeRuneInString
的计算版本,并做了性能测试 相关回复在这里 发现两个种方法性能差距惊人。我想到了 go-extend 中的
exstrings.Reverse
方法也是用了类似的类型转换,所以我做了一个小的实验来测试不同实现的性能。