From f34785da02dfbdc6b78ab7cbd1e47ec3cb1c7416 Mon Sep 17 00:00:00 2001 From: David Finkel 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 }