mirror of
https://github.com/golang/go
synced 2024-11-18 01:54:45 -07:00
reflect: clean up IsZero and isZero
For 'case Array' in IsZero, check 'v.flag&flagIndir == 0' in the first place, also rename 'array' to 'typ' for consistency. Simplify comments for 'isZero' and its uses. Add line breaks for long sentence in 'isZero'.
This commit is contained in:
parent
6382893890
commit
4307fdf729
@ -1598,24 +1598,22 @@ func (v Value) IsZero() bool {
|
||||
case Complex64, Complex128:
|
||||
return v.Complex() == 0
|
||||
case Array:
|
||||
array := (*abi.ArrayType)(unsafe.Pointer(v.typ()))
|
||||
// Avoid performance degradation of small benchmarks.
|
||||
if v.flag&flagIndir == 0 {
|
||||
return v.ptr == nil
|
||||
}
|
||||
typ := (*abi.ArrayType)(unsafe.Pointer(v.typ()))
|
||||
// If the type is comparable, then compare directly with zero.
|
||||
if array.Equal != nil && array.Size() <= maxZero {
|
||||
if v.flag&flagIndir == 0 {
|
||||
return v.ptr == nil
|
||||
}
|
||||
if typ.Equal != nil && typ.Size() <= maxZero {
|
||||
// v.ptr doesn't escape, as Equal functions are compiler generated
|
||||
// and never escape. The escape analysis doesn't know, as it is a
|
||||
// function pointer call.
|
||||
return array.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
|
||||
return typ.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
|
||||
}
|
||||
if array.TFlag&abi.TFlagRegularMemory != 0 {
|
||||
// For some types where the zero value is a value where all bits of this type are 0
|
||||
// optimize it.
|
||||
return isZero(unsafe.Slice(((*byte)(v.ptr)), array.Size()))
|
||||
if typ.TFlag&abi.TFlagRegularMemory != 0 {
|
||||
// For types of all bits are 0, optimize it.
|
||||
return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
|
||||
}
|
||||
n := int(array.Len)
|
||||
n := int(typ.Len)
|
||||
for i := 0; i < n; i++ {
|
||||
if !v.Index(i).IsZero() {
|
||||
return false
|
||||
@ -1637,8 +1635,7 @@ func (v Value) IsZero() bool {
|
||||
return typ.Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
|
||||
}
|
||||
if typ.TFlag&abi.TFlagRegularMemory != 0 {
|
||||
// For some types where the zero value is a value where all bits of this type are 0
|
||||
// optimize it.
|
||||
// For types of all bits are 0, optimize it.
|
||||
return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
|
||||
}
|
||||
|
||||
@ -1656,14 +1653,14 @@ func (v Value) IsZero() bool {
|
||||
}
|
||||
}
|
||||
|
||||
// isZero For all zeros, performance is not as good as
|
||||
// return bytealg.Count(b, byte(0)) == len(b)
|
||||
// For all zeros, performance is not as good as
|
||||
// returning bytealg.Count(b, byte(0)) == len(b).
|
||||
func isZero(b []byte) bool {
|
||||
if len(b) == 0 {
|
||||
return true
|
||||
}
|
||||
const n = 32
|
||||
// Align memory addresses to 8 bytes
|
||||
// Align memory addresses to 8 bytes.
|
||||
for uintptr(unsafe.Pointer(&b[0]))%8 != 0 {
|
||||
if b[0] != 0 {
|
||||
return false
|
||||
@ -1690,7 +1687,14 @@ func isZero(b []byte) bool {
|
||||
w = w[1:]
|
||||
}
|
||||
for len(w) >= n {
|
||||
if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 || w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 || w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 || w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 || w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 || w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 || w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 || w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 {
|
||||
if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 ||
|
||||
w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 ||
|
||||
w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 ||
|
||||
w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 ||
|
||||
w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 ||
|
||||
w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 ||
|
||||
w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 ||
|
||||
w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 {
|
||||
return false
|
||||
}
|
||||
w = w[n:]
|
||||
|
Loading…
Reference in New Issue
Block a user