From ecaa25fabaf0b205310016ab63cc5ac53bb3c4f3 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 4 Jun 2022 13:18:11 +0900 Subject: [PATCH] internal/affine: avoid heap allocations by casting a variable to a concrete type This is a dirty hack but seems efficient. Closes #2119 --- internal/affine/colorm.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/affine/colorm.go b/internal/affine/colorm.go index a5ea1bdb9..95ea2f7e9 100644 --- a/internal/affine/colorm.go +++ b/internal/affine/colorm.go @@ -520,10 +520,21 @@ func (c colorMImplScale) Equals(other ColorM) bool { func (c *colorMImplBodyTranslate) Equals(other ColorM) bool { var lhsb [16]float32 var lhst [4]float32 - other.Elements(&lhsb, &lhst) - rhsb := &c.body - rhst := &c.translate - return lhsb == *rhsb && lhst == *rhst + + // Calling a method of an interface type escapes arguments to heap (#2119). + // Instead, cast `other` to a concrete type and call `Elements` functions of it. + switch other := other.(type) { + case ColorMIdentity: + other.Elements(&lhsb, &lhst) + case colorMImplScale: + other.Elements(&lhsb, &lhst) + case *colorMImplBodyTranslate: + other.Elements(&lhsb, &lhst) + default: + panic("affine: unexpected ColorM implementation") + } + + return lhsb == c.body && lhst == c.translate } func (c ColorMIdentity) Concat(other ColorM) ColorM {