From e48d7d3b21d39f8cf82e7e2547bd9ce47df68dde Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 25 Jan 2021 18:04:55 -0800 Subject: [PATCH] [dev.typeparams] go/constant: faster match implementation Shortcut matching code if both operands have the same representation. Change-Id: I9433455acb5b9d0b88d3c81eb1b3b0ae258193e7 Reviewed-on: https://go-review.googlesource.com/c/go/+/286654 Trust: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- src/go/constant/value.go | 73 +++++++++++++++------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/src/go/constant/value.go b/src/go/constant/value.go index 8ee7620609..78cb3f896f 100644 --- a/src/go/constant/value.go +++ b/src/go/constant/value.go @@ -1035,62 +1035,45 @@ func ord(x Value) int { // or invalid (say, nil) both results are that value. // func match(x, y Value) (_, _ Value) { - if ord(x) > ord(y) { - y, x = match(y, x) - return x, y + switch ox, oy := ord(x), ord(y); { + case ox < oy: + x, y = match0(x, y) + case ox > oy: + y, x = match0(y, x) } - // ord(x) <= ord(y) + return x, y +} +// match0 must only be called by match. +// Invariant: ord(x) < ord(y) +func match0(x, y Value) (_, _ Value) { // Prefer to return the original x and y arguments when possible, // to avoid unnecessary heap allocations. - switch x1 := x.(type) { - case boolVal, *stringVal, complexVal: - return x, y - - case int64Val: - switch y.(type) { - case int64Val: - return x, y - case intVal: - return i64toi(x1), y - case ratVal: - return i64tor(x1), y - case floatVal: - return i64tof(x1), y - case complexVal: - return vtoc(x1), y - } - + switch y.(type) { case intVal: - switch y.(type) { - case intVal: - return x, y - case ratVal: - return itor(x1), y - case floatVal: - return itof(x1), y - case complexVal: - return vtoc(x1), y + switch x1 := x.(type) { + case int64Val: + return i64toi(x1), y } - case ratVal: - switch y.(type) { - case ratVal: - return x, y - case floatVal: - return rtof(x1), y - case complexVal: - return vtoc(x1), y + switch x1 := x.(type) { + case int64Val: + return i64tor(x1), y + case intVal: + return itor(x1), y } - case floatVal: - switch y.(type) { - case floatVal: - return x, y - case complexVal: - return vtoc(x1), y + switch x1 := x.(type) { + case int64Val: + return i64tof(x1), y + case intVal: + return itof(x1), y + case ratVal: + return rtof(x1), y } + case complexVal: + return vtoc(x), y } // force unknown and invalid values into "x position" in callers of match