有没有一种方法可以在不检查每个元素或使用reflect的情况下检查字节片是空还是0?
theByteVar := make([]byte, 128)
if "theByteVar is empty or zeroes" {
doSomething()
}
字符串
我发现的一个看起来很奇怪的解决方案是保留一个空字节数组用于比较。
theByteVar := make([]byte, 128)
emptyByteVar := make([]byte, 128)
// fill with anything
theByteVar[1] = 2
if reflect.DeepEqual(theByteVar,empty) == false {
doSomething(theByteVar)
}
型
肯定有更好/更快的解决方案。
谢啦,谢啦
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
型
4条答案
按热度按时间frebpwbc1#
将它与另一个只包含零的切片进行比较,这需要阅读(并比较)2个切片。
在这里使用一个for循环会更有效:
字符串
如果你确实需要在多个地方使用它,请将它 Package 在一个实用程序函数中:
型
然后使用它:
型
lmvvr0a82#
另一个解决方案借用了C.它可以通过使用Go中的
unsafe
包来实现。这个想法很简单,我们可以在每个步骤中检查
byte[i:i+8]
的值,而不是检查[]byte中的每个字节。通过这样做,我们可以在每次迭代中检查8个字节,而不是只检查一个字节。下面的代码不是最佳实践,只是展示了想法。
字符串
基准测试
测试用例:
仅测试最差情况(所有元素均为零)
方法:
unsafe
封装解决方案bytes.Compare
解决方案,预分配固定大小的空字节数组。bytes.Compare
解决方案,无需预先分配固定大小的空字节数组。结果
型
摘要
假设我们谈论的是稀疏零字节数组中的条件。根据基准测试,如果性能是一个问题,那么天真的检查解决方案将是一个坏主意。而且,如果你不想在你的项目中使用
unsafe
包,那么可以考虑使用预分配空数组的bytes.Compare
解决方案作为替代方案。可以指出的一个有趣的点是,来自
unsafe
包的性能变化很大,但它基本上优于上述所有其他解决方案。我认为这与CPU缓存机制有关。j1dl9f463#
你可以使用bytes.equal或bytes.contains来与初始化为零的字节片进行比较,参见https://play.golang.org/p/mvUXaTwKjP,我还没有检查性能,但希望它已经被优化了。如果需要,您可能希望尝试其他解决方案并比较性能数字。
tpgth1q74#
我认为如果在循环内部使用
binary or
而不是if condition
会更好(更快):字符串
通过使用前面的答案中提到的
uint64
的想法,可以进一步优化这一点