mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
reflect: make Value an opaque struct
Making Value opaque means we can drop the interface kludges in favor of a significantly simpler and faster representation. v.Kind() will be a prime candidate for inlining too. On a Thinkpad X201s using -benchtime 10: benchmark old ns/op new ns/op delta json.BenchmarkCodeEncoder 284391780 157415960 -44.65% json.BenchmarkCodeMarshal 286979140 158992020 -44.60% json.BenchmarkCodeDecoder 717175800 388288220 -45.86% json.BenchmarkCodeUnmarshal 734470500 404548520 -44.92% json.BenchmarkCodeUnmarshalReuse 707172280 385258720 -45.52% json.BenchmarkSkipValue 24630036 18557062 -24.66% benchmark old MB/s new MB/s speedup json.BenchmarkCodeEncoder 6.82 12.33 1.81x json.BenchmarkCodeMarshal 6.76 12.20 1.80x json.BenchmarkCodeDecoder 2.71 5.00 1.85x json.BenchmarkCodeUnmarshal 2.64 4.80 1.82x json.BenchmarkCodeUnmarshalReuse 2.74 5.04 1.84x json.BenchmarkSkipValue 77.92 103.42 1.33x I cannot explain why BenchmarkSkipValue gets faster. Maybe it is one of those code alignment things. R=iant, r, gri, r CC=golang-dev https://golang.org/cl/5373101
This commit is contained in:
parent
4d27f64863
commit
a479a45548
3 changed files with 752 additions and 745 deletions
|
|
@ -16,6 +16,13 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
func TestBool(t *testing.T) {
|
||||
v := ValueOf(true)
|
||||
if v.Bool() != true {
|
||||
t.Fatal("ValueOf(true).Bool() = false")
|
||||
}
|
||||
}
|
||||
|
||||
type integer int
|
||||
type T struct {
|
||||
a int
|
||||
|
|
@ -215,7 +222,8 @@ func TestTypes(t *testing.T) {
|
|||
|
||||
func TestSet(t *testing.T) {
|
||||
for i, tt := range valueTests {
|
||||
v := ValueOf(tt.i).Elem()
|
||||
v := ValueOf(tt.i)
|
||||
v = v.Elem()
|
||||
switch v.Kind() {
|
||||
case Int:
|
||||
v.SetInt(132)
|
||||
|
|
@ -1100,21 +1108,38 @@ func TestMethod(t *testing.T) {
|
|||
}
|
||||
|
||||
// Curried method of value.
|
||||
i = ValueOf(p).Method(1).Call([]Value{ValueOf(10)})[0].Int()
|
||||
tfunc := TypeOf(func(int) int(nil))
|
||||
v := ValueOf(p).Method(1)
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Value Method returned %d; want 250", i)
|
||||
}
|
||||
i = ValueOf(p).MethodByName("Dist").Call([]Value{ValueOf(10)})[0].Int()
|
||||
v = ValueOf(p).MethodByName("Dist")
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Value MethodByName returned %d; want 250", i)
|
||||
}
|
||||
|
||||
// Curried method of pointer.
|
||||
i = ValueOf(&p).Method(1).Call([]Value{ValueOf(10)})[0].Int()
|
||||
v = ValueOf(&p).Method(1)
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Pointer Value Method returned %d; want 250", i)
|
||||
}
|
||||
i = ValueOf(&p).MethodByName("Dist").Call([]Value{ValueOf(10)})[0].Int()
|
||||
v = ValueOf(&p).MethodByName("Dist")
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Pointer Value MethodByName returned %d; want 250", i)
|
||||
}
|
||||
|
|
@ -1129,11 +1154,19 @@ func TestMethod(t *testing.T) {
|
|||
}
|
||||
}{p}
|
||||
pv := ValueOf(s).Field(0)
|
||||
i = pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
|
||||
v = pv.Method(0)
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Interface Method returned %d; want 250", i)
|
||||
}
|
||||
i = pv.MethodByName("Dist").Call([]Value{ValueOf(10)})[0].Int()
|
||||
v = pv.MethodByName("Dist")
|
||||
if tt := v.Type(); tt != tfunc {
|
||||
t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
|
||||
}
|
||||
i = v.Call([]Value{ValueOf(10)})[0].Int()
|
||||
if i != 250 {
|
||||
t.Errorf("Interface MethodByName returned %d; want 250", i)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue