This only triggers a few places in the stdlib,
but it helps a lot when it does.
Before:
runtime.mapassign1 t=1 size=2400 args=0x20 locals=0xe0
After:
runtime.mapassign1 t=1 size=2352 args=0x20 locals=0xd8
name old time/op new time/op delta
MapPop100-8 19.8µs ±11% 18.4µs ± 9% -7.16% (p=0.000 n=20+19)
MapPop1000-8 367µs ±17% 335µs ±11% -8.63% (p=0.000 n=19+19)
MapPop10000-8 7.29ms ±15% 6.86ms ±12% -5.84% (p=0.020 n=20+20)
Change-Id: I9faf32f95a6ba6a6d5d0818eab32cc271e01d10a
Reviewed-on: https://go-review.googlesource.com/26666
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
}
}
+func eqval(a, b Val) bool {
+ if a.Ctype() != b.Ctype() {
+ return false
+ }
+ switch x := a.U.(type) {
+ default:
+ Fatalf("unexpected Ctype for %T", a.U)
+ panic("not reached")
+ case *NilVal:
+ return true
+ case bool:
+ y := b.U.(bool)
+ return x == y
+ case *Mpint:
+ y := b.U.(*Mpint)
+ return x.Cmp(y) == 0
+ case *Mpflt:
+ y := b.U.(*Mpflt)
+ return x.Cmp(y) == 0
+ case *Mpcplx:
+ y := b.U.(*Mpcplx)
+ return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
+ case string:
+ y := b.U.(string)
+ return x == y
+ }
+}
+
type NilVal struct{}
// IntLiteral returns the Node's literal value as an integer.
case OINDEX:
return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
+
+ case OLITERAL:
+ return eqval(l.Val(), r.Val())
}
return false