Commit 780f5b71 authored by Rémy Oudompheng's avatar Rémy Oudompheng

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
parent f2380a81
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment