Skip to content

Commit 6e30e8e

Browse files
committed
reflect: cache IsVariadic in Call
Taking a look at a CPU profile, IsVariadic was calculated multiple times unnecessarily. I also added a new BechmarkCallMethod to measure this use-case. name old time/op new time/op delta Call-16 20.3ns ± 8% 20.3ns ±16% ~ (p=0.443 n=18+20) CallMethod-16 99.2ns ± 3% 90.1ns ± 2% -9.22% (p=0.000 n=20+17) CallArgCopy/size=128-16 15.0ns ± 2% 14.5ns ± 3% -2.76% (p=0.000 n=20+19) CallArgCopy/size=256-16 15.9ns ± 7% 15.3ns ± 5% -4.26% (p=0.000 n=20+20) CallArgCopy/size=1024-16 17.6ns ± 7% 17.2ns ± 6% -1.73% (p=0.044 n=19+20) CallArgCopy/size=4096-16 25.3ns ± 4% 24.9ns ± 4% -1.66% (p=0.016 n=18+20) CallArgCopy/size=65536-16 375ns ± 4% 376ns ± 4% ~ (p=0.644 n=20+20) name old alloc/op new alloc/op delta Call-16 0.00B 0.00B ~ (all equal) CallMethod-16 0.00B 0.00B ~ (all equal) name old allocs/op new allocs/op delta Call-16 0.00 0.00 ~ (all equal) CallMethod-16 0.00 0.00 ~ (all equal) name old speed new speed delta CallArgCopy/size=128-16 8.56GB/s ± 2% 8.80GB/s ± 3% +2.84% (p=0.000 n=20+19) CallArgCopy/size=256-16 16.1GB/s ± 6% 16.8GB/s ± 5% +4.45% (p=0.000 n=20+20) CallArgCopy/size=1024-16 58.2GB/s ± 7% 59.4GB/s ± 6% +2.16% (p=0.026 n=20+20) CallArgCopy/size=4096-16 161GB/s ± 4% 165GB/s ± 4% +1.95% (p=0.007 n=17+20) CallArgCopy/size=65536-16 175GB/s ± 4% 174GB/s ± 4% ~ (p=0.640 n=20+20) Updates golang#7818 Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
1 parent 27156a6 commit 6e30e8e

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

src/reflect/value.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,9 @@ func (v Value) call(op string, in []Value) []Value {
375375

376376
isSlice := op == "CallSlice"
377377
n := t.NumIn()
378+
isVariadic := t.IsVariadic()
378379
if isSlice {
379-
if !t.IsVariadic() {
380+
if !isVariadic {
380381
panic("reflect: CallSlice of non-variadic function")
381382
}
382383
if len(in) < n {
@@ -386,13 +387,13 @@ func (v Value) call(op string, in []Value) []Value {
386387
panic("reflect: CallSlice with too many input arguments")
387388
}
388389
} else {
389-
if t.IsVariadic() {
390+
if isVariadic {
390391
n--
391392
}
392393
if len(in) < n {
393394
panic("reflect: Call with too few input arguments")
394395
}
395-
if !t.IsVariadic() && len(in) > n {
396+
if !isVariadic && len(in) > n {
396397
panic("reflect: Call with too many input arguments")
397398
}
398399
}
@@ -406,7 +407,7 @@ func (v Value) call(op string, in []Value) []Value {
406407
panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
407408
}
408409
}
409-
if !isSlice && t.IsVariadic() {
410+
if !isSlice && isVariadic {
410411
// prepare slice for remaining values
411412
m := len(in) - n
412413
slice := MakeSlice(t.In(n), m, m)

0 commit comments

Comments
 (0)