美文网首页
golang 两个数组过滤多种算法 benchmark效率对比

golang 两个数组过滤多种算法 benchmark效率对比

作者: cowkeys | 来源:发表于2016-11-15 12:58 被阅读0次

    说明

    之前做的go项目,遇到一个关于数组的增删效率问题:

    循环数组--判断--删除数组--得到需要的数组

    示例:
    如果我需要在arr1中过滤掉arr2
    第一次写的方法如下

    arr1:=[]int{1,2,3......,999,1000}
    arr2:=[]int{5,10,15......,995,1000}
    for k, v := range arr1{
            for _, vv := range arr2{
                    if v == vv {
                        arr1= append(arr1[:k], arr1[k+1:]...)
                    }
            }
    }
    

    这样写会出现错误,因为删除一个数之后,数标就对不上了,因此需要倒序删除:

    for i := len(arr1) - 1; i >= 0; i-- {
            v := arr1[i]
            for _, vv := range arr2 {
                if v == vv {
                    arr1 = append(arr1[:i], arr1[i+1:]...)
                }
            }
        }
    

    还有一种方法,就是不删除,用一个新的temparr来append:

        arr1 := []int{1, 2, 3, 5, 6, 7, 8, 9}
        var temp []int
        for _, v := range arr1 {
            exist := false
            for _, vv := range arr2 {
                if v == vv {
                    exist = true
                }
            }
            if !exist {
                temp = append(temp, v)
            }
        }
    

    对比

    测试源码 github-demo
    通过golang的Benchmark来进行测试,
    结果如下:

    第一种,删除方法 第二种,temp添加方法

    结果

    这个测试用例在1s中内运行了20000次,每次调用大约用了86660ns、97710ns
    可以看到 对数组使用删除的方式会增加效率,当然,我觉得没什么太大的区别。。仅仅用来测试一下

    更新:

    如果 数组的长度越大,运行时间会越长,如果将arr2先转换为map,则时间复杂度由n^2 变为 2n,少了一个数量级。
    方法汇总如下

    package main
    
    import (
        "fmt"
        "testing"
    )
    
    var (
        arr2   []int
        arrMap map[int]bool
    )
    
    func init() {
        arrMap = make(map[int]bool, 0)
        for i := 1000; i < 10000; i++ {
            arr2 = append(arr2, i)
            arrMap[i] = true
        }
    }
    
    func main() {
        One()
        Two()
        Three()
        Four()
    }
    
    // panic
    func One() {
        arr1 := []int{1, 2, 3, 5, 6, 7, 8, 9}
    
        defer func() {
            if err := recover(); err != nil {
                fmt.Println("panic ", err)
            }
        }()
        for k, v := range arr1 {
            for _, vv := range arr2 {
                if v == vv {
                    arr1 = append(arr1[:k], arr1[k+1:]...)
                }
            }
        }
    
        fmt.Println(arr1, len(arr1))
    }
    
    func Two() []int {
        arr1 := []int{1, 2, 3, 5, 6, 7, 8, 9}
    
        for i := len(arr1) - 1; i >= 0; i-- {
            v := arr1[i]
            for _, vv := range arr2 {
                if v == vv {
                    arr1 = append(arr1[:i], arr1[i+1:]...)
                }
            }
        }
        return arr1
    }
    
    func Three() []int {
        arr1 := []int{1, 2, 3, 5, 6, 7, 8, 9}
    
        var temp []int
        for _, v := range arr1 {
            exist := false
            for _, vv := range arr2 {
                if v == vv {
                    exist = true
                }
            }
            if !exist {
                temp = append(temp, v)
            }
        }
        return arr1
    }
    
    func Four() []int {
        arr1 := []int{1, 2, 3, 5, 6, 7, 8, 9}
        var temp []int
    
        for _, v := range arr1 {
            if !arrMap[v] {
                temp = append(temp, v)
            }
        }
        return temp
    }
    
    func BenchmarkTwo(b *testing.B) {
        for n := 0; n < b.N; n++ {
            Two()
        }
    }
    
    func BenchmarkThree(b *testing.B) {
        for n := 0; n < b.N; n++ {
            Three()
        }
    }
    
    func BenchmarkFour(b *testing.B) {
        for n := 0; n < b.N; n++ {
            Four()
        }
    }
    
    
    go test -bench=.
    
    ➜  array go test -bench=.
    goos: linux
    goarch: amd64
    pkg: test/array
    BenchmarkTwo-12            50000             33427 ns/op
    BenchmarkThree-12          50000             33378 ns/op
    BenchmarkFour-12        10000000               183 ns/op
    PASS
    ok      test/array      6.041s
    

    相关文章

      网友评论

          本文标题:golang 两个数组过滤多种算法 benchmark效率对比

          本文链接:https://www.haomeiwen.com/subject/umnkpttx.html