Skip to main content
Go Container provides multiple backing-store implementations for Queue and Stack, so you can tune for your workload. For Set and OrderedMap, only one implementation is available, and it is already well-optimized for general use.

Available implementations

TypeSliceMapListList + sync.PoolList + internal poolRecommended
OrderedMapSlice with size hint
QueueSlice with size hint
WaitableQueueSlice with size hint
SetMap with size hint
StackSlice with size hint

When to use each

The slice-backed implementation is the fastest option in almost every benchmark, particularly when you supply a size hint to preallocate the backing array. Start here unless you have a specific reason to choose otherwise.
  • Best throughput for both Enqueue/Push and Dequeue/Pop
  • Preallocating with a size hint eliminates most allocations in the steady state
  • Consistent top-ranked performance across Go 1.18 and Go 1.24, on both amd64 and arm64

List

A doubly-linked list that allocates one node per element. Avoids resizing the backing structure when you do not know the capacity in advance, but allocation overhead per operation is significantly higher than a preallocated slice.
  • No amortized resize penalty when the working set is unbounded
  • Higher per-operation allocation cost (heap node per element)
  • A good fallback if you genuinely cannot estimate capacity

ListWithInternalPool (ListIP)

A linked list that recycles nodes using an internal pool. This reduces allocation pressure compared to a plain List, and comes close to Slice performance in several benchmarks—but never surpasses it.
  • Better than plain List; useful when you want to avoid sync.Pool
  • Still slower than Slice with a size hint

ListWithSyncPool (ListSP)

A linked list that recycles nodes using sync.Pool. In practice this is the slowest option across all benchmarks and architectures.
Avoid ListWithSyncPool unless you have profiled your application and measured a concrete benefit. Benchmark data consistently shows it ranking last in nearly every operation.

The sizeHint parameter

Every constructor accepts a sizeHint int argument. When you pass a positive value, the implementation preallocates backing storage for that many elements, avoiding allocations until the collection grows beyond that capacity.
// Preallocate for 128 elements — fastest path
q := queue.NewSliceQueue[MyEvent](128)

// No hint — backing storage grows on demand
q := queue.NewSliceQueue[MyEvent](0)
Use a size hint whenever you have a reasonable estimate of the working-set size. Even an approximate value improves throughput significantly; it does not need to be exact.

Creating each variant

Queue

import "github.com/fgm/container/queue"

// With size hint (preferred)
q := queue.NewSliceQueue[string](64)

// Without size hint
q := queue.NewSliceQueue[string](0)

Stack

import "github.com/fgm/container/stack"

// With size hint (preferred)
s := stack.NewSliceStack[int](64)

// Without size hint
s := stack.NewSliceStack[int](0)

OrderedMap

Only the slice-backed implementation is available. Pass stable: true for in-place updates (highest throughput), or stable: false for recency-based ordering (LRU-style).
import "github.com/fgm/container/orderedmap"

om := orderedmap.NewSlice[string, int](64, true /* stable */)
om.Store("requests", 42)
v, loaded := om.Load("requests")
om.Delete("requests")

Set

Only the map-backed implementation is available.
import "github.com/fgm/container/set"

s := set.NewBasicMap[string](32)
s.Add("go")
s.Add("go")      // idempotent
fmt.Println(s.Contains("go")) // true

Quick recommendation summary

Use caseRecommendation
Queue or Stack — general useNewSliceQueue / NewSliceStack with size hint
Queue or Stack — unknown capacity at creationNewSliceQueue / NewSliceStack with 0, or NewListInternalPoolQueue / NewListInternalPoolStack
Concurrent producer-consumer queueNewWaitableQueue (see Concurrency)
Ordered maporderedmap.NewSlice with size hint
Setset.NewBasicMap with size hint
When in doubt, reach for NewSliceQueue or NewSliceStack with a size hint. This is the recommended default for most workloads and consistently outperforms all other options in benchmarks.