Skip to content

Configuration

This guide explains the various configuration options available in HNSW and how they affect performance.

Graph Parameters

When creating a new HNSW graph, you can configure several parameters to optimize performance for your specific use case:

graph := hnsw.NewGraph[int]()

// Configure the graph
graph.M = 16              // Maximum number of connections per node
graph.EfConstruction = 200 // Size of the dynamic candidate list during construction
graph.EfSearch = 100       // Size of the dynamic candidate list during search
graph.Distance = hnsw.CosineDistance // Distance function to use

M (Maximum Connections)

The M parameter controls the maximum number of connections per node in the graph. A higher value of M results in a more connected graph, which can improve search accuracy but increases memory usage and construction time.

  • Default value: 16
  • Recommended range: 8-64
  • Effect on performance:
  • Higher values improve search accuracy but increase memory usage and construction time
  • Lower values reduce memory usage and construction time but may reduce search accuracy

EfConstruction

The EfConstruction parameter controls the size of the dynamic candidate list during graph construction. A higher value results in a more accurate graph but increases construction time.

  • Default value: 200
  • Recommended range: 100-500
  • Effect on performance:
  • Higher values improve graph quality but increase construction time
  • Lower values reduce construction time but may reduce graph quality

EfSearch

The EfSearch parameter controls the size of the dynamic candidate list during search. A higher value results in more accurate search results but increases search time.

  • Default value: 100
  • Recommended range: 50-200
  • Effect on performance:
  • Higher values improve search accuracy but increase search time
  • Lower values reduce search time but may reduce search accuracy

Distance Functions

HNSW provides several built-in distance functions:

// Euclidean distance
graph.Distance = hnsw.EuclideanDistance

// Cosine distance
graph.Distance = hnsw.CosineDistance

// Dot product distance
graph.Distance = hnsw.DotProductDistance

You can also define your own distance function:

graph.Distance = func(a, b []float32) float32 {
    // Custom distance calculation
    var sum float32
    for i := range a {
        sum += (a[i] - b[i]) * (a[i] - b[i])
    }
    return sum
}

Performance Tuning

Here are some tips for tuning HNSW for optimal performance:

Memory vs. Speed Trade-off

  • For faster search at the cost of more memory, increase M and EfSearch
  • For lower memory usage at the cost of slower search, decrease M and EfSearch

Construction Time vs. Search Quality Trade-off

  • For faster construction at the cost of search quality, decrease EfConstruction
  • For better search quality at the cost of longer construction time, increase EfConstruction

Batch Operations

For better performance when adding many vectors, use batch operations:

nodes := []hnsw.Node[int]{
    {Key: 1, Value: []float32{0.1, 0.2, 0.3}},
    {Key: 2, Value: []float32{0.2, 0.3, 0.4}},
    {Key: 3, Value: []float32{0.3, 0.4, 0.5}},
}
err := graph.BatchAdd(nodes)

Configuration Examples

High Accuracy Configuration

graph := hnsw.NewGraph[int]()
graph.M = 32
graph.EfConstruction = 400
graph.EfSearch = 200

Fast Construction Configuration

graph := hnsw.NewGraph[int]()
graph.M = 12
graph.EfConstruction = 100
graph.EfSearch = 50

Balanced Configuration

graph := hnsw.NewGraph[int]()
graph.M = 16
graph.EfConstruction = 200
graph.EfSearch = 100

Next Steps

Now that you understand how to configure HNSW, you can explore more features: