• 【小实验】golang的if比较中的string/[]byte转换会被编译器优化


    之前做了实验,[]byte类型使用string()进行转换的时候,会产生拷贝。see: 【小测试】golang中使用string()来转换[]byte数组产生了拷贝

    不过今天又有了新的认识。请先看下面的benchmark测试:

    // goos: windows
    // goarch: amd64
    // pkg: git.woa.com/ahfuzhang/go_proxy/internal
    // cpu: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
    // BenchmarkStringCompare
    // BenchmarkStringCompare-8        15305848                73.45 ns/op
    func BenchmarkStringCompare(b *testing.B) {
    	buf := make([]byte, 1024)
    	for i := 0; i < cap(buf); i++ {
    		buf[i] = byte(rand.Intn(125-32) + 32)
    	}
    	total := 0
    	for n := 0; n < b.N; n++ {
    		start1 := rand.Intn(len(buf))
    		len1 := rand.Intn(len(buf) - start1)
    		start2 := rand.Intn(len(buf))
    		len2 := rand.Intn(len(buf) - start2)
    		if bytes.Compare(buf[start1:start1+len1], buf[start2:start2+len2]) == 0 {
    			total++
    		}
    	}
    }
    
    // goos: windows
    // goarch: amd64
    // pkg: git.woa.com/ahfuzhang/go_proxy/internal
    // cpu: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
    // BenchmarkStringCompare1
    // BenchmarkStringCompare1-8       16340803                69.47 ns/op
    func BenchmarkStringCompare1(b *testing.B) {
    	buf := make([]byte, 1024)
    	for i := 0; i < cap(buf); i++ {
    		buf[i] = byte(rand.Intn(125-32) + 32)
    	}
    	total := 0
    	for n := 0; n < b.N; n++ {
    		start1 := rand.Intn(len(buf))
    		len1 := rand.Intn(len(buf) - start1)
    		start2 := rand.Intn(len(buf))
    		len2 := rand.Intn(len(buf) - start2)
    		if string(buf[start1:start1+len1]) == string(buf[start2:start2+len2]) {
    			total++
    		}
    	}
    }
    
    // goos: windows
    // goarch: amd64
    // pkg: git.woa.com/ahfuzhang/go_proxy/internal
    // cpu: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
    // BenchmarkStringCompare2
    // BenchmarkStringCompare2-8        4692843               263.5 ns/op
    func BenchmarkStringCompare2(b *testing.B) {
    	buf := make([]byte, 1024)
    	for i := 0; i < cap(buf); i++ {
    		buf[i] = byte(rand.Intn(125-32) + 32)
    	}
    	total := 0
    	for n := 0; n < b.N; n++ {
    		start1 := rand.Intn(len(buf))
    		len1 := rand.Intn(len(buf) - start1)
    		start2 := rand.Intn(len(buf))
    		len2 := rand.Intn(len(buf) - start2)
    		s1 := string(buf[start1 : start1+len1])
    		s2 := string(buf[start2 : start2+len2])
    		if s1 == s2 {
    			total++
    		}
    	}
    }
    

    同样是字符串的==比较,在if中直接转换,对于转换赋值后再比较,性能相差几倍。

    golang官方库的源码也看到了类似的注释:

    //C:\Go\src\bytes\bytes.go
    // Equal reports whether a and b
    // are the same length and contain the same bytes.
    // A nil argument is equivalent to an empty slice.
    func Equal(a, b []byte) bool {
    	// Neither cmd/compile nor gccgo allocates for these string conversions.
    	return string(a) == string(b)
    }
    

    看来是编译器对if语句这里的比较做了特殊优化。

  • 相关阅读:
    SharpReader的效率:支持meme聚合
    RSS阅读器:从订阅到发现之旅?
    关于word使用WildCards进行查找和替换
    Cannot resolve plugin org.apache.maven.plugins:mavencleanplugin:2.5
    MyBatis
    python matplotlib中axes与axis subplot的区别是什么?
    MyBatis中settings属性配置详解
    IDEA中 Project 和 Module 的区别
    Pycharm 运行程序后如何 如何查看变量的值(不通过debug的方式)
    查看oracle是否正常、表空间 (AIX)
  • 原文地址:https://www.cnblogs.com/ahfuzhang/p/15879423.html
Copyright © 2020-2023  润新知