isZeroBytes is an optimized version of this loop: for i := range b { if b[i] != 0 { return false } } return true This implementation significantly reduces the CPU footprint of checking for slices to be zero, especially when the length increases (these cases should be rare tho). name
(b []byte)
| 84 | // IsZeroBytes7 3.97ns ± 4% 3.26ns ± 3% -18.02% (p=0.000 n=10+10) |
| 85 | // IsZeroBytes64K 14.8µs ± 3% 1.9µs ± 3% -87.34% (p=0.000 n=10+10) |
| 86 | func isZeroBytes(b []byte) bool { |
| 87 | if n := len(b) / 8; n != 0 { |
| 88 | if !isZeroUint64(*(*[]uint64)(unsafe.Pointer(&sliceHeader{ |
| 89 | Data: unsafe.Pointer(&b[0]), |
| 90 | Len: n, |
| 91 | Cap: n, |
| 92 | }))) { |
| 93 | return false |
| 94 | } |
| 95 | b = b[n*8:] |
| 96 | } |
| 97 | switch len(b) { |
| 98 | case 7: |
| 99 | return bto32(b) == 0 && bto16(b[4:]) == 0 && b[6] == 0 |
| 100 | case 6: |
| 101 | return bto32(b) == 0 && bto16(b[4:]) == 0 |
| 102 | case 5: |
| 103 | return bto32(b) == 0 && b[4] == 0 |
| 104 | case 4: |
| 105 | return bto32(b) == 0 |
| 106 | case 3: |
| 107 | return bto16(b) == 0 && b[2] == 0 |
| 108 | case 2: |
| 109 | return bto16(b) == 0 |
| 110 | case 1: |
| 111 | return b[0] == 0 |
| 112 | default: |
| 113 | return true |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | func bto32(b []byte) uint32 { |
| 118 | return *(*uint32)(unsafe.Pointer(&b[0])) |
searching dependent graphs…