Performance 是否有更有效的函数来查找[]字节相似性?

Performance 是否有更有效的函数来查找[]字节相似性?,performance,go,byte,Performance,Go,Byte,我正在寻找一种有效的方法来查找两个字节片之间的前缀相似性。我目前正在使用这个,但如果可能的话,我正在寻找一种更有效的方法 多谢各位 s1 -> [0 15 136 96 88 76 0 0 0 1] s2 -> [0 15 136 96 246 1 255 255 255 255] output -> [0 15 136 96] func-bytesimilar(s1[]字节,s2[]字节)[]字节{ 用于!字节。相等(s1,s2){ s1=s1[:len(s1)-1]

我正在寻找一种有效的方法来查找两个字节片之间的前缀相似性。我目前正在使用这个,但如果可能的话,我正在寻找一种更有效的方法

多谢各位

s1 -> [0 15 136 96 88 76 0 0 0 1] 
s2 -> [0 15 136 96 246 1 255 255 255 255]

output -> [0 15 136 96] 
func-bytesimilar(s1[]字节,s2[]字节)[]字节{
用于!字节。相等(s1,s2){
s1=s1[:len(s1)-1]
s2=s2[:len(s2)-1]
}
返回s1
}
基准代码:

func BenchmarkBytePrefix200(b *testing.B) {
    s1 := []byte{0, 15, 136, 96, 88, 76, 0, 0, 0, 1}
    s2 := []byte{0, 15, 136, 96, 246, 1, 255, 255, 255, 255}
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        bytePrefix(s1, s2)
    }
}

我的观点是,从上面的代码来看,下面的部分在I/O资源上非常昂贵

s1 = s1[:len(s1)-1]
s2 = s2[:len(s2)-1]
实际上,我们可以做一个简单的循环,当发现不同的字节时尽早退出。使用这种方法,我们不需要太多的内存分配过程。代码行数更多,但性能更好

代码如下

func bytesSimilar2(s1 []byte, s2 []byte) []byte {
    l1 := len(s1)
    l2 := len(s2)
    least := l1
    if least > l2 {
        least = l2
    }
    count := 0
    for i := 0; i < least; i++ {
        if s1[i] == s2[i] {
            count++
            continue
        }
        break
    }
    if count == 0 {
        return []byte{}
    }
    return s1[:count]
}

func BenchmarkBytePrefix200v1(b *testing.B) {
    s1 := []byte{0, 15, 136, 96, 88, 76, 0, 0, 0, 1}
    s2 := []byte{0, 15, 136, 96, 246, 1, 255, 255, 255, 255}
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        bytesSimilar1(s1, s2)
    }
}

func BenchmarkBytePrefix200v2(b *testing.B) {
    s1 := []byte{0, 15, 136, 96, 88, 76, 0, 0, 0, 1}
    s2 := []byte{0, 15, 136, 96, 246, 1, 255, 255, 255, 255}
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        bytesSimilar2(s1, s2)
    }
}

如果问题中的
bytePrefix
bytesimilar
相同:

func BytesSimilarNew(s1 []byte, s2 []byte) []byte {
    for i := 0; i < len(s1); i++ {
        if s1[i] ^ s2[i] > 0 {
            return s1[:i]
        }
    }
    return []byte{}
}

你还试过什么?你能发布
bytePrefix
func的实现吗?我只看到了
bytesimilar
func的实现。这对于[1,2,3]和[1,7,3]这样的数组是不正确的。是的@Veedrac,它只用于从左到右识别相似前缀。谢谢@dmkvl,是的,我在发布之前刚刚重命名了它,忘记了更正名称。@eober,发生了,我想是的。
a^b>0
不应该比
a!=b
,所以只需使用
=@Veedrac,你确定吗?请提供证据。
BenchmarkByteSimilarXor-8 209317736 5.24 ns/op BenchmarkByteSimilarInequality-8 224361943 5.32 ns/op
@Veedrac,是的,谢谢Arief。我感谢你的帮助。
goos: darwin
goarch: amd64
pkg: git.kanosolution.net/kano/acl
BenchmarkBytePrefix200v1-8      27184414                38.7 ns/op             0 B/op          0 allocs/op
BenchmarkBytePrefix200v2-8      161031307                7.40 ns/op            0 B/op          0 allocs/op
PASS
func BytesSimilarNew(s1 []byte, s2 []byte) []byte {
    for i := 0; i < len(s1); i++ {
        if s1[i] ^ s2[i] > 0 {
            return s1[:i]
        }
    }
    return []byte{}
}
BenchmarkBytePrefix200
BenchmarkBytePrefix200-8        28900861            36.5 ns/op         0 B/op          0 allocs/op
BenchmarkByteSimilarNew200
BenchmarkByteSimilarNew200-8    237646268            5.06 ns/op        0 B/op          0 allocs/op
PASS