zoukankan      html  css  js  c++  java
  • GoLang字符串比较(一)

    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
    ", 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
    ", 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是最快的一种字符串比较的方式。本文测试方式并不是很地道,不是非常的严谨,关于如何更加准确的测试,我将在明天的文章中跟大家一起分享一下。

  • 相关阅读:
    MySQL高级(十五)--- 主从复制
    MySQL高级(十四)--- 行锁
    MySQL高级(十三)--- 表锁
    MySQL高级(十二)--- 全局查询日志
    MySQL高级知识(十一)--- Show Profile
    MySQL高级(十)--- 批量插入数据脚本
    MySQL高级(九)--- 慢查询日志
    MySQL高级(八)--- ORDER BY优化
    MySQL高级(七)--- 索引面试题分析
    SpringBoot系列教程web篇之如何自定义参数解析器
  • 原文地址:https://www.cnblogs.com/double12gzh/p/13683791.html
Copyright © 2011-2022 走看看