From f34785da02dfbdc6b78ab7cbd1e47ec3cb1c7416 Mon Sep 17 00:00:00 2001
From: David Finkel <davidf@vimeo.com>
Date: Tue, 9 Apr 2024 17:53:19 -0400
Subject: [PATCH] protocodec: make a few tweaks to allow inlining

protocodec.GalaxyGet is particularly hot, and trivial so it should get
inlined. Make a few tweaks to allow inlining. (bringing the cost down
below the magic 80 number in the go compiler)

Similarly, split up protocodec.backendGetterV2.Get to allow inlining of
the fast path. (Amusingly, this also allows the new `setSlow` to inline,
but that wasn't the goal)
---
 protocodec/backend_getter_v2.go | 25 ++++++++++++++-----------
 protocodec/galaxywrap_v2.go     | 10 +++++-----
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/protocodec/backend_getter_v2.go b/protocodec/backend_getter_v2.go
index 4c309660..0d4cf108 100644
--- a/protocodec/backend_getter_v2.go
+++ b/protocodec/backend_getter_v2.go
@@ -30,19 +30,22 @@ func (b backendGetterV2[C, T]) Get(ctx context.Context, key string, dest galaxyc
 	if bgErr != nil {
 		return bgErr
 	}
-	switch d := dest.(type) {
-	case *CodecV2[C, T]:
+	if d, ok := dest.(*CodecV2[C, T]); ok {
 		d.Set(out)
-	default:
-		vs, mErr := proto.Marshal(out)
-		if mErr != nil {
-			return fmt.Errorf("failed to marshal value as bytes: %w", mErr)
-		}
-
-		if uErr := dest.UnmarshalBinary(vs); uErr != nil {
-			return fmt.Errorf("destination codec (type %T) Unmarshal failed: %w", dest, uErr)
-		}
+		return nil
 	}
+	return b.setSlow(out, dest)
 
+}
+
+func (b backendGetterV2[C, T]) setSlow(out T, dest galaxycache.Codec) error {
+	vs, mErr := proto.Marshal(out)
+	if mErr != nil {
+		return fmt.Errorf("failed to marshal value as bytes: %w", mErr)
+	}
+
+	if uErr := dest.UnmarshalBinary(vs); uErr != nil {
+		return fmt.Errorf("destination codec (type %T) Unmarshal failed: %w", dest, uErr)
+	}
 	return nil
 }
diff --git a/protocodec/galaxywrap_v2.go b/protocodec/galaxywrap_v2.go
index 5529845c..ff24574b 100644
--- a/protocodec/galaxywrap_v2.go
+++ b/protocodec/galaxywrap_v2.go
@@ -10,11 +10,11 @@ import (
 
 // GalaxyGet is a simple wrapper around a Galaxy.Get method-call that takes
 // care of constructing the protocodec.CodecV2, etc. (making the interface more idiomatic for Go)
-func GalaxyGet[C any, T pointerMessage[C]](ctx context.Context, g *galaxycache.Galaxy, key string) (T, error) {
-	pc := NewV2[C, T]()
-	getErr := g.Get(ctx, key, &pc)
+func GalaxyGet[C any, T pointerMessage[C]](ctx context.Context, g *galaxycache.Galaxy, key string) (m T, getErr error) {
+	pc := CodecV2[C, T]{}
+	getErr = g.Get(ctx, key, &pc)
 	if getErr != nil {
-		return nil, getErr
+		return // use named return values to bring the inlining cost down
 	}
-	return pc.Get(), nil
+	return pc.msg, nil
 }