Go bindings for hnswlib — a fast approximate nearest neighbor search library based on Hierarchical Navigable Small World graphs.
hnswlib compatibility: synced with hnswlib master.
- Go 1.21+
- C++ compiler with C++11 support (g++ or clang++)
- Make
go get github.com/sunhailin-Leo/hnswlib-to-goBefore building your Go program, the C++ static library must be compiled:
cd $GOPATH/pkg/mod/github.com/sunhailin-Leo/hnswlib-to-go@<version>
make buildOr clone and build from source:
git clone --recurse-submodules https://github.com/sunhailin-Leo/hnswlib-to-go.git
cd hnswlib-to-go
make buildpackage main
import (
"fmt"
hnswgo "github.com/sunhailin-Leo/hnswlib-to-go"
)
func main() {
// Create a new index
// dim=128, M=16, efConstruction=200, randomSeed=42, maxElements=10000
index := hnswgo.New(128, 16, 200, 42, 10000, hnswgo.SpaceL2)
defer index.Free()
// Set search-time ef parameter
index.SetEf(50)
// Add vectors
vector := make([]float32, 128)
for i := range vector {
vector[i] = float32(i) * 0.01
}
index.AddPoint(vector, 0)
// Search for nearest neighbors
labels, distances := index.SearchKNN(vector, 5)
fmt.Println("Labels:", labels)
fmt.Println("Distances:", distances)
// Save and load
index.Save("/tmp/my_index.bin")
loaded := hnswgo.Load("/tmp/my_index.bin", 128, hnswgo.SpaceL2)
defer loaded.Free()
}| Function | Description |
|---|---|
New(dim, M, efConstruction, randSeed, maxElements, spaceType) |
Create a new HNSW index |
NewWithReplaceDeleted(dim, M, efConstruction, randSeed, maxElements, spaceType) |
Create index with replace-deleted support |
Load(location, dim, spaceType) |
Load index from file |
| Parameter | Type | Description |
|---|---|---|
dim |
int |
Vector dimension |
M |
int |
Max connections per layer (see ALGO_PARAMS.md) |
efConstruction |
int |
Construction-time ef parameter (see ALGO_PARAMS.md) |
randSeed |
int |
Random seed |
maxElements |
uint32 |
Maximum number of elements |
spaceType |
string |
Distance metric ("l2", "ip", or "cosine") |
| Constant | Value | Description |
|---|---|---|
SpaceL2 |
"l2" |
Euclidean (L2) distance |
SpaceIP |
"ip" |
Inner product distance |
SpaceCosine |
"cosine" |
Cosine similarity (auto-normalizes vectors) |
| Method | Description |
|---|---|
AddPoint(vector, label) |
Add a single vector |
AddPointWithReplace(vector, label) |
Add vector, reusing deleted slots |
AddBatchPoints(vectors, labels, coroutines) |
Add vectors concurrently |
SearchKNN(vector, N) |
Search for N nearest neighbors |
SearchBatchKNN(vectors, N, coroutines) |
Batch search concurrently |
GetVectorByLabel(label) |
Retrieve stored vector by label |
| Method | Description |
|---|---|
Save(location) |
Persist index to file |
Free() |
Release index memory |
SetEf(ef) |
Set search-time ef parameter |
SetNormalize(bool) |
Enable/disable vector normalization |
ResizeIndex(newMaxElements) |
Resize index capacity |
| Method | Description |
|---|---|
MarkDelete(label) |
Soft-delete an element |
UnmarkDelete(label) |
Restore a soft-deleted element |
GetLabelIsMarkedDeleted(label) |
Check if element is deleted |
UpdatePoint(vector, label, prob) |
Update vector for existing label |
UpdateBatchPoints(vectors, labels, probs, coroutines) |
Batch update concurrently |
| Method | Description |
|---|---|
GetMaxElements() |
Maximum capacity |
GetCurrentElementCount() |
Current number of elements |
GetDeleteCount() |
Number of soft-deleted elements |
make build # Build C++ library and Go package
make opt # Build with -O3 and -march=native
make portable # Build without -march=native (CI-friendly)
make test # Run unit tests
make bench # Run benchmarks
make clean # Remove build artifacts
make help # Show all available targetsRequires appropriate cross-compilation toolchains:
make build-linux-amd64 # Build for Linux x86_64
make build-linux-arm64 # Build for Linux aarch64
make build-darwin-amd64 # Build for macOS x86_64
make build-darwin-arm64 # Build for macOS ARM64
make build-windows-amd64 # Build for Windows x86_64 (MinGW)Windows builds require MSYS2 with MinGW-w64:
# Install MSYS2, then in MINGW64 shell:
pacman -S mingw-w64-x86_64-gcc make
make buildMeasured on Apple M3 Pro, Go 1.23, -O3 -march=native, dim=128, 5000 indexed vectors:
| Benchmark | ns/op | B/op | allocs/op |
|---|---|---|---|
| AddPoint (L2) | 1,805,974 | 512 | 1 |
| AddPoint (Cosine) | 1,476,631 | 512 | 1 |
| AddBatchPoints (1000×4 goroutines) | 2,949,077,675 | 454 | 9 |
| SearchKNN (L2, top-10) | 119,831 | 96 | 2 |
| SearchKNN (Cosine, top-10) | 89,467 | 96 | 2 |
| SearchBatchKNN (100×4 goroutines) | 4,231,052 | 15,650 | 211 |
| SaveLoad (5000 vectors) | 16,149,372 | 50 | 1 |
Run benchmarks locally:
make opt # Build with -O3 -march=native
make bench # Run all benchmarksSee CHANGELOG.md for detailed release notes.
- v1.1.0 — Synced hnswlib to latest master; performance optimizations; Windows support; comprehensive tests & benchmarks; GitHub Actions CI (Go 1.21–1.26)
- v1.0.4 — Added
UpdatePoint,UpdateBatchPoints - v1.0.3 — Added
GetMaxElements,GetCurrentElementCount,GetDeleteCount,GetVectorByLabel - v1.0.2 — Updated hnswlib to 0.7.0; added batch operations, delete/unmark, resize
- v1.0.1 — Code formatting; experimental
UnloadAPI - v1.0.0 — Initial release (hnswlib 0.5.2)
MIT — see LICENSE for details.