1
0
mirror of https://github.com/golang/go synced 2024-11-17 05:14:56 -07:00

reflect: do not cache trivial values in DeepEqual.

DeepEqual caches addresses of compared values
each time it visits addressable values. This is
more expensive than actually comparing them in
the common case of large slices of bytes or integers.

Also add a fast path for slices with identical
underlying array.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13000044
This commit is contained in:
Rémy Oudompheng 2013-09-05 21:37:07 +02:00
parent f2380a81d7
commit 780f5b714d

View File

@ -28,8 +28,15 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
}
// if depth > 10 { panic("deepValueEqual") } // for debugging
hard := func(k Kind) bool {
switch k {
case Array, Map, Slice, Struct:
return true
}
return false
}
if v1.CanAddr() && v2.CanAddr() {
if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
addr1 := v1.UnsafeAddr()
addr2 := v2.UnsafeAddr()
if addr1 > addr2 {
@ -71,6 +78,9 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
if v1.Len() != v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for i := 0; i < v1.Len(); i++ {
if !deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) {
return false
@ -98,6 +108,9 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
if v1.Len() != v2.Len() {
return false
}
if v1.Pointer() == v2.Pointer() {
return true
}
for _, k := range v1.MapKeys() {
if !deepValueEqual(v1.MapIndex(k), v2.MapIndex(k), visited, depth+1) {
return false