From ea650abf829d8d4456ffd16956f2141b5893525d Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 26 Jan 2022 12:20:48 -0800 Subject: [PATCH 1/2] Optimize evictedQueue impl and use Avoid unnecessary allocations in the recordingSpan by using an evictedQueue type instead of a pointer to one. Lazy allocate the evictedQueue queue to prevent unnecessary operations for spans without any use of the queue. Document the evictedQueue --- sdk/trace/evictedqueue.go | 17 +++++++++-------- sdk/trace/span.go | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sdk/trace/evictedqueue.go b/sdk/trace/evictedqueue.go index 3c5817a6a02..4a75fffe188 100644 --- a/sdk/trace/evictedqueue.go +++ b/sdk/trace/evictedqueue.go @@ -14,24 +14,25 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" +// evictedQueue is a FIFO queue with a configurable capacity. type evictedQueue struct { queue []interface{} capacity int droppedCount int } -func newEvictedQueue(capacity int) *evictedQueue { - eq := &evictedQueue{ - capacity: capacity, - queue: make([]interface{}, 0), - } - - return eq +func newEvictedQueue(capacity int) evictedQueue { + // Do not pre-allocate queue, do this lazily. + return evictedQueue{capacity: capacity} } +// add adds value to the evictedQueue eq. If eq is at capacity, the oldest +// queued value will be discarded the drop count incremented. func (eq *evictedQueue) add(value interface{}) { if len(eq.queue) == eq.capacity { - eq.queue = eq.queue[1:] + // Drop first-in while avoiding allocating more capacity to eq.queue. + copy(eq.queue[:eq.capacity-1], eq.queue[1:]) + eq.queue = eq.queue[:eq.capacity-1] eq.droppedCount++ } eq.queue = append(eq.queue, value) diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 41a68b58551..0111c475895 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -142,10 +142,10 @@ type recordingSpan struct { attributes *attributesMap // events are stored in FIFO queue capped by configured limit. - events *evictedQueue + events evictedQueue // links are stored in FIFO queue capped by configured limit. - links *evictedQueue + links evictedQueue // executionTracerTaskEnd ends the execution tracer span. executionTracerTaskEnd func() From 968a9cb7c61675ebdee3f6db9908a44bcf697e19 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 26 Jan 2022 12:57:26 -0800 Subject: [PATCH 2/2] Fix grammar --- sdk/trace/evictedqueue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/trace/evictedqueue.go b/sdk/trace/evictedqueue.go index 4a75fffe188..8e89e19d4b9 100644 --- a/sdk/trace/evictedqueue.go +++ b/sdk/trace/evictedqueue.go @@ -27,7 +27,7 @@ func newEvictedQueue(capacity int) evictedQueue { } // add adds value to the evictedQueue eq. If eq is at capacity, the oldest -// queued value will be discarded the drop count incremented. +// queued value will be discarded and the drop count incremented. func (eq *evictedQueue) add(value interface{}) { if len(eq.queue) == eq.capacity { // Drop first-in while avoiding allocating more capacity to eq.queue.