以下哪一种方法在性能方面更好?
绝对不是这个。
str := "large text"
str2 := []byte(str)
for _, s := range str2 {
// use s
}
字符串是不可变的。[]byte
是可变的。这意味着[]byte(str)
制作副本。所以上面将复制整个字符串。我发现不知道何时复制字符串成为大字符串性能问题的主要来源。
如果str2
从不更改,编译器可能会优化掉副本。出于这个原因,最好像这样编写上面的代码,以确保字节数组永远不会改变。
str := "large text"
for _, s := range []byte(str) {
// use s
}
这样就str2
不可能在以后进行修改并破坏优化。
但这是一个坏主意,因为它会破坏任何多字节字符。见下文。
至于字节/符文转换,性能不是考虑因素,因为它们并不等效。c
将是一个符文,str[i]
将是一个字节。如果您的字符串包含多字节字符,则必须使用符文。
例如...
package main
import(
"fmt"
)
func main() {
str := "snow ☃ man"
for i, c := range str {
fmt.Printf("c:%c str[i]:%c\n", c, str[i])
}
}
$ go run ~/tmp/test.go
c:s str[i]:s
c:n str[i]:n
c:o str[i]:o
c:w str[i]:w
c: str[i]:
c:☃ str[i]:â
c: str[i]:
c:m str[i]:m
c:a str[i]:a
c:n str[i]:n
请注意,使用str[i]
会破坏多字节 Unicode 雪人,它仅包含多字节字符的第一个字节。
无论如何都没有性能差异,因为range str
已经必须逐个字符地完成工作,而不是逐个字节。