From ca3c94428bb6606198bff58c3d91aa22718c0bb0 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 }