> ## Documentation Index
> Fetch the complete documentation index at: https://osinet.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Choosing an Implementation

> Pick the right backing store for your Queue or Stack.

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

| Type          | Slice | Map | List | List + sync.Pool | List + internal pool | Recommended          |
| ------------- | :---: | :-: | :--: | :--------------: | :------------------: | -------------------- |
| OrderedMap    |   ✓   |     |      |                  |                      | Slice with size hint |
| Queue         |   ✓   |     |   ✓  |         ✓        |           ✓          | Slice with size hint |
| WaitableQueue |   ✓   |     |      |                  |                      | Slice with size hint |
| Set           |       |  ✓  |      |                  |                      | Map with size hint   |
| Stack         |   ✓   |     |   ✓  |         ✓        |           ✓          | Slice with size hint |

## When to use each

### Slice (recommended default)

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.

<Warning>
  Avoid `ListWithSyncPool` unless you have profiled your application and measured a concrete benefit. Benchmark data consistently shows it ranking last in nearly every operation.
</Warning>

## 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.

```go theme={null}
// 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

<CodeGroup>
  ```go Slice (recommended) theme={null}
  import "github.com/fgm/container/queue"

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

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

  ```go List theme={null}
  import "github.com/fgm/container/queue"

  q := queue.NewListQueue[string](0)
  ```

  ```go ListWithInternalPool theme={null}
  import "github.com/fgm/container/queue"

  q := queue.NewListInternalPoolQueue[string](64)
  ```

  ```go ListWithSyncPool theme={null}
  import "github.com/fgm/container/queue"

  q := queue.NewListSyncPoolQueue[string](0)
  ```
</CodeGroup>

### Stack

<CodeGroup>
  ```go Slice (recommended) theme={null}
  import "github.com/fgm/container/stack"

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

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

  ```go List theme={null}
  import "github.com/fgm/container/stack"

  s := stack.NewListStack[int](0)
  ```

  ```go ListWithInternalPool theme={null}
  import "github.com/fgm/container/stack"

  s := stack.NewListInternalPoolStack[int](64)
  ```

  ```go ListWithSyncPool theme={null}
  import "github.com/fgm/container/stack"

  s := stack.NewListSyncPoolStack[int](0)
  ```
</CodeGroup>

### 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).

```go theme={null}
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.

```go theme={null}
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 case                                      | Recommendation                                                                                         |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Queue or Stack — general use                  | `NewSliceQueue` / `NewSliceStack` with size hint                                                       |
| Queue or Stack — unknown capacity at creation | `NewSliceQueue` / `NewSliceStack` with `0`, or `NewListInternalPoolQueue` / `NewListInternalPoolStack` |
| Concurrent producer-consumer queue            | `NewWaitableQueue` (see [Concurrency](/guides/concurrency))                                            |
| Ordered map                                   | `orderedmap.NewSlice` with size hint                                                                   |
| Set                                           | `set.NewBasicMap` with size hint                                                                       |

<Tip>
  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.
</Tip>
