在 golang 中不能直接用 len 函数来统计字符串长度, 查看了下源码发现字符串是以 UTF-8 为格式存储的, 说明 len 函数是取得包含 byte 的个数
- // string is the set of all strings of 8-bit bytes, conventionally but not
- // necessarily representing UTF-8-encoded text. A string may be empty, but
- // not nil. Values of string type are immutable.
举个例子,"Hello, 世界"(因为, 对比所以用了中文)
- s := "Hello, 世界"
- fmt.Println(len(s)) // 13
- fmt.Println([]byte(s)) // [72 101 108 108 111 44 32 228 184 150 231 149 140]
既然是以 byte 存储的, 那自然就想到了取 byte 的长度
- - bytes.Count()
- - strings.Count()
- 将字符串转换为 []runee 后调用 len 函数
- 使用 utf8.RuneCountInString()
- package main
- import (
- "bytes"
- "fmt"
- "strings"
- "testing"
- "unicode/utf8"
- )
- /*
- 在 golang 中不能直接用 len 函数来统计字符串长度, 查看了下源码发现字符串是以 UTF-8 为格式存储的, 说明 len 函数是取得包含 byte 的个数
- */
- func main() {
- s := "hello, 世界"
- fmt.Println(len(s)) // 13
- fmt.Println([]byte(s)) // [72 101 108 108 111 44 32 228 184 150 231 149 140]
- fmt.Print(f1(s))
- }
- func f1(s string) int {
- return bytes.Count([]byte(s), nil) - 1
- }
- func f2(s string) int {
- return strings.Count(s, "") - 1
- }
- func f3(s string) int {
- return len([]rune(s))
- }
- func f4(s string) int {
- return utf8.RuneCountInString(s)
- }
- var s = "Hello, 世界"
- func Benchmark1(b *testing.B) {
- for i := 0; i < b.N; i++ {
- f1(s)
- }
- }
- func Benchmark2(b *testing.B) {
- for i := 0; i < b.N; i++ {
- f2(s)
- }
- }
- func Benchmark3(b *testing.B) {
- for i := 0; i < b.N; i++ {
- f3(s)
- }
- }
- func Benchmark4(b *testing.B) {
- for i := 0; i < b.N; i++ {
- f4(s)
- }
- }
在 golang ldea 配置中我没有看到 benchamark 配置, 总说包不对, 在命令行中输入
go test stringCount_test.go -bench ".*"
得到以下结果
- Benchmark1-12 100000000 17.7 ns/op
- Benchmark2-12 100000000 14.0 ns/op
- Benchmark3-12 100000000 14.5 ns/op
- Benchmark4-12 100000000 13.1 ns/op
最快的是 utf8.RuneCountInString()
来源: https://www.cnblogs.com/zrds/p/11356334.html