From 5966af70f4afff9d9a2aaff008ad0793ff534417 Mon Sep 17 00:00:00 2001 From: Mitsuo Heijo Date: Sat, 8 May 2021 08:00:57 +0900 Subject: [PATCH] contrib/go-redis/redis.v8: optimize BeforeProcess and BeforeProcessPipeline This change includes the following three optimizations. 1. The previous implementation split the command with strings.Split, but only the 0th element is actually needed as a tag for span. Therefore, use strings.IndexByte to find the first space and slice the raw command string. 2. Replace the length derivation of args with the counting of the number of spaces. 3. The number of ddtrace.StartSpanOptions is often pre-determined, so make it in advance to reduce allocation. --- contrib/go-redis/redis.v8/redis.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contrib/go-redis/redis.v8/redis.go b/contrib/go-redis/redis.v8/redis.go index 497e78bd61..afa9728e20 100644 --- a/contrib/go-redis/redis.v8/redis.go +++ b/contrib/go-redis/redis.v8/redis.go @@ -100,16 +100,16 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio func (ddh *datadogHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { raw := cmd.String() - parts := strings.Split(raw, " ") - length := len(parts) - 1 + length := strings.Count(raw, " ") p := ddh.params - opts := []ddtrace.StartSpanOption{ + opts := make([]ddtrace.StartSpanOption, 0, 5+len(ddh.additionalTags)+1) // 5 options below + for additionalTags + for analyticsRate + opts = append(opts, tracer.SpanType(ext.SpanTypeRedis), tracer.ServiceName(p.config.serviceName), - tracer.ResourceName(parts[0]), + tracer.ResourceName(raw[:strings.IndexByte(raw, ' ')]), tracer.Tag("redis.raw_command", raw), tracer.Tag("redis.args_length", strconv.Itoa(length)), - } + ) opts = append(opts, ddh.additionalTags...) if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate)) @@ -132,18 +132,18 @@ func (ddh *datadogHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error func (ddh *datadogHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) { raw := commandsToString(cmds) - parts := strings.Split(raw, " ") - length := len(parts) - 1 + length := strings.Count(raw, " ") p := ddh.params - opts := []ddtrace.StartSpanOption{ + opts := make([]ddtrace.StartSpanOption, 0, 7+len(ddh.additionalTags)+1) // 7 options below + for additionalTags + for analyticsRate + opts = append(opts, tracer.SpanType(ext.SpanTypeRedis), tracer.ServiceName(p.config.serviceName), - tracer.ResourceName(parts[0]), + tracer.ResourceName(raw[:strings.IndexByte(raw, ' ')]), tracer.Tag("redis.raw_command", raw), tracer.Tag("redis.args_length", strconv.Itoa(length)), tracer.Tag(ext.ResourceName, raw), tracer.Tag("redis.pipeline_length", strconv.Itoa(len(cmds))), - } + ) opts = append(opts, ddh.additionalTags...) if !math.IsNaN(p.config.analyticsRate) { opts = append(opts, tracer.Tag(ext.EventSampleRate, p.config.analyticsRate))