如何检查[] byte是否为全零

Jin*_*mcg 5 go slice

有没有一种方法可以检查字节片是否为空或为0,而无需检查每个元素或不使用反射?

theByteVar := make([]byte, 128)

if "theByteVar is empty or zeroes" {
   doSomething()
}
Run Code Online (Sandbox Code Playgroud)

我发现似乎很奇怪的一种解决方案是保留一个空字节数组以进行比较。

theByteVar := make([]byte, 128)
emptyByteVar := make([]byte, 128)

// fill with anything
theByteVar[1] = 2

if reflect.DeepEqual(theByteVar,empty) == false {
   doSomething(theByteVar)
}
Run Code Online (Sandbox Code Playgroud)

当然,必须有一个更好的/更快速的解决方案。

谢谢

UPDATE对1000个循环做了一些比较,而反射方式是迄今为止最差的。

Equal Loops: 1000 in true in 19.197µs
Contains Loops: 1000 in true in 34.507µs
AllZero Loops: 1000 in true in 117.275µs
Reflect Loops: 1000 in true in 14.616277ms
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 6

将它与另一个只包含零的切片进行比较,这需要读取(并比较)2 个切片。

在这里使用单个 for 循环会更有效:

for _, v := range theByteVar {
    if v != 0 {
        doSomething(theByteVar)
        break
    }
}
Run Code Online (Sandbox Code Playgroud)

如果确实需要在多个地方使用它,请将其包装在一个实用程序函数中:

func allZero(s []byte) bool {
    for _, v := range s {
        if v != 0 {
            return false
        }
    }
    return true
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

if !allZero(theByteVar) {
    doSomething(theByteVar)
}
Run Code Online (Sandbox Code Playgroud)

  • 这样做的一个优势是,如果做得正确,您将利用 CPU L1 缓存优化,例如英特尔的静态读取预测。这就是为什么 Go 语言让你只迭代集合中的项目,而不是使用一些花哨的内置抽象扩展。只要您保持结构对齐,并且您正在巧妙地使用 L1。例如,如果经常交换字节,您可能希望将这些位存储在 int64 中:这样您就可以减少 L1 缓存失效。 (4认同)

Rav*_*i R 3

您可以使用 bytes.Equal 或 bytes.Contains 与零初始化的字节切片进行比较,请参阅https://play.golang.org/p/mvUXaTwKjP,我还没有检查性能,但希望它已经过优化。如果需要,您可能想尝试其他解决方案并比较性能数据。