1. 写在前面
微信公众号:[double12gzh]
关注容器技术、关注
Kubernetes
。问题或建议,请公众号留言。
在GoLang的使用过程中,我们难免会遇到字符串比较
的问题。不知道您有没有总结过,如何做字符串比较
呢?在本文中我将向在家展示一下,如何进行字符串比较
。 全文将按如下三个方面进行介绍:
- 字符串比较的不同方式
- 忽略大小的字符串比较
- 不同方法的性能比较
2. 字符串比较基本方式
2.1 区分大小写
相信看到这个题目,您的第一直觉肯定是So easy
,也相信您也能很快的写出如下的代码:
package main
import "fmt"
func main() {
srcString := "This a string"
destString := "this a string"
if srcString == destString {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
2.2 不区分大小写
2.2.1 使用strings.ToLower
package main
import (
"fmt"
"strings"
)
func main() {
...
if strings.ToLower(srcString) == strings.ToLower(destString) {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
2.2.2 使用strings.Compare
package main
import (
"fmt"
"strings"
)
func main() {
...
if strings.Compare(strings.ToLower(srcString), strings.ToLower(destString)) == 0 {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
这种方法比2.2.1
中提到的方式更加优雅和高效,在工作中,如果涉及到不区分大小的字符串的比较时,我也经常会采用这样的方式。
3. 使用EqualFold
这种方式是不区分大小的。这种方法比
2.2
中提到的方法更高的高效。
package main
import (
"fmt"
"strings"
)
func main() {
...
if strings.EqualFold(srcString, destString) == true {
fmt.Println("Equals")
} else {
fmt.Println("Not Equals")
}
}
4. 性能分析
我们前面只是简单的给出了结论,哪种方式是比较高效的。那样是不严谨的,那么,如何来实际测试一下,看一下,到底哪种方式更加的高效呢? 这一章节中,我们将会通过一个测试样本进行实际测试一下。
4.1 生成数据样本
在开始之前,我们需要所准备一个数据样本,样本的获取可以通过mockaroo来得到,也可以使用以下程序来生成:
package main
import (
"crypto/rand"
"fmt"
"os"
)
func GenerateRandomString(n int) string {
const CHARACTER = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var bytes = make([]byte, n)
if _, err := rand.Read(bytes); err != nil {
panic(err)
}
for i, c := range bytes {
bytes[i] = CHARACTER[c % byte(len(CHARACTER))]
}
return string(bytes)
}
func GenFile() {
f, err := os.Create("mock_data.txt")
if err != nil {
panic(err)
}
defer f.Close()
var tempStr string
for i := 0; i < 200000; i++ {
tempStr = fmt.Sprintf("%v\n", GenerateRandomString(16))
if _, err2 := f.WriteString(tempStr); err2 != nil {
panic(err2)
}
}
}
func main() {
GenFile()
}
我们得到了一个200000行数据的数据样本:
jeffrey@hacker ~/Desktop/hello
$ cat mock_data.txt | wc -l
200000
4.2 测试读取耗时
为了测试读取文件的耗时,我们写了以下程序:
main.go
package main
import "main/utils/reader"
func main() {
//gen.GenFile()
reader.ReadFile("mock_data.txt")
}
reader.go
package reader
import (
"bufio"
"fmt"
"os"
)
func ReadFile(fileName string) {
f, err := os.Open(fileName)
if err != nil {
panic(err)
}
scan := bufio.NewScanner(f)
scan.Split(bufio.ScanLines)
for scan.Scan() {
cmptString := scan.Text()
fmt.Printf("%s\n", cmptString)
}
f.Close()
}
执行上面获取文件的代码,耗时如下:
...
IBg0Fg79uIwwX9aF
ZcLmE0v1eUqjb6yK
EH6ykTgMTiUBtg3c
aVPont9anIcYBxcW
nKj04D2QIwx1J3VA
bwDRBkuRuw6XDn2I
79rIt3yb8zp5EMRw
real 0m1.122s
user 0m0.000s
sys 0m0.015s
jeffrey@hacker ~/Desktop/hello
4.3 区分大小写时的耗时
4.3.1 采用==
时的耗时
这里测试直接使用==
来判断字符串是否相等时的耗时:
func BasicCompare(src, dest string) bool {
if srcString == destString {
return true
} else {
return false
}
}
main.go
package main
import "main/utils/reader"
func main() {
//gen.GenFile()
reader.ReadFile("mock_data.txt")
}
reader.go
package reader
import (
"bufio"
"fmt"
"os"
)
func ReadFile(fileName string) {
srcString := "fuckSBWu"
f, err := os.Open(fileName)
if err != nil {
panic(err)
}
scan := bufio.NewScanner(f)
scan.Split(bufio.ScanLines)
for scan.Scan() {
if BasicCompare(scan.Text(), strcString) {
fmt.Println("Equal")
}
}
f.Close()
}
看一下执行时间:
jeffrey@hacker ~/Desktop/hello
$ time go run main.go
real 0m0.436s
user 0m0.000s
sys 0m0.015s
4.3.2 使用Compare
时的耗时
func CompareCompare(src, dest string) bool {
if strings.Compare(src, dest) == 0 {
return true
}
return false
}
jeffrey@hacker ~/Desktop/hello
$ time go run main.go
real 0m0.395s
user 0m0.000s
sys 0m0.015s
4.3.3 结论
strings.Compare()略显快一些。
4.4 不区分大小写时的耗时
4.4.1 使用==
时的耗时
func CaseInSensitiveBasicCompare(src, dest string) bool {
if strings.ToLower(src) == strings.ToLower(dest) {
return true
} else {
return false
}
}
jeffrey@hacker ~/Desktop/hello
$ time go run main.go
real 0m0.423s
user 0m0.000s
sys 0m0.015s
4.4.2 使用Compare
时的耗时
func CaseInSensitiveCompareCompare(src, dest string) bool {
if strings.Compare(strings.ToLower(src), strings.ToLower(dest)) == 0 {
return true
} else {
return false
}
}
jeffrey@hacker ~/Desktop/hello
$ time go run main.go
real 0m0.426s
user 0m0.015s
sys 0m0.000s
4.4.3 使用EqualFold时的耗时
jeffrey@hacker ~/Desktop/hello
$ time go run main.go
real 0m0.394s
user 0m0.015s
sys 0m0.000s
5. 总结
EqualFold
是最快的一种字符串比较的方式。本文测试方式并不是很地道
,不是非常的严谨,关于如何更加准确的测试,我将在明天的文章中跟大家一起分享一下。