Cosine, Euclidean, Manhattan. Text embedding. Disk persistence. Brute-force nearest-neighbor search. Zero allocations on distance computation. All pure Go.
package main import "github.com/BackendStack21/go-vector/pkg/vector" func main() { store := vector.NewStore(vector.CosineDistance) store.Add("cat", vector.Vector{1.0, 0.8, 0.1}) store.Add("dog", vector.Vector{0.9, 0.7, 0.1}) store.Add("car", vector.Vector{0.1, 0.0, 0.9}) query := vector.Vector{1.0, 0.9, 0.1} results := store.Search(query, 2) for _, r := range results { fmt.Printf("%s: %.4f\n", r.ID, r.Distance) } // cat: 0.0005 // dog: 0.0026 }
Ten vector operations, four distance metrics, and a production-ready in-memory vector store. All zero-allocation on read paths.
Dot product, norm, normalize, add, subtract, scale. Full suite of vector operations with zero-overhead []float32.
Cosine, Euclidean, Manhattan, Dot Product. Single-pass computation. Choose lower-is-better or higher-is-better sorting.
Add, get, remove, search. Top-K nearest-neighbor with any metric. Cloned outputs — no accidental mutation.
Built-in Random Projections embedder (Johnson-Lindenstrauss). Bring your own OpenAI or Ollama adapter via the Embedder interface.
Gob-encode your store to disk. Full roundtrip with metric preservation. JSON export for debugging. ~60MB per 10K vectors at 1536d.
Standard library only. No CGo, no BLAS, no syscalls, no I/O. Compiles anywhere Go runs.
Built-in Random Projections embedder using the Johnson-Lindenstrauss lemma. Deterministic, zero-dependency, ~10µs per document. Or bring your own via the Embedder interface.
Sparse random projection matrix — each vocabulary token contributes to ~33% of output dimensions. Vocabulary built from your corpus. Output always L2-normalized.
rp := vector.NewRandomProjections(256) rp.Fit(corpus) v, _ := rp.Embed("machine learning") // v is a 256-dim normalized Vector
Implement the Embedder interface to plug in OpenAI, Ollama, or sentence-transformers. One method to implement per backend. Your search code never changes.
type Embedder interface { Embed(text string) (Vector, error) Dims() int } // OpenAIEmbedder, OllamaEmbedder, etc. var emb vector.Embedder = NewOpenAIEmbedder()
Gob-encode your entire store to a file. Restore with metric and all data intact. JSON export for debugging and inspection.
Binary encoding via encoding/gob. Full roundtrip preserves IDs, vectors, and metric. ~200ms save for 10K vectors at 1536d.
store.Save("/data/vectors.db") restored := vector.NewStore(...) restored.Load("/data/vectors.db") // all data + metric restored
Export as indented JSON for debugging, inspection, or cross-language interop. Same roundtrip guarantees.
store.SaveJSON("/data/vectors.json") restored.LoadJSON("/data/vectors.json")
All benchmarks at 1536 dimensions (typical embedding size) on AMD EPYC. Single-pass Cosine and Euclidean — no intermediate vector allocations.
| Operation | Latency | Allocs |
|---|---|---|
| Dot | 7.5 µs | 0 |
| Cosine | 9.4 µs | 0 |
| Euclidean | 8.7 µs | 0 |
| Manhattan | 9.4 µs | 0 |
| Search 100 vectors | 3.2 ms | 63 KB |
| Search 1,000 vectors | 28.5 ms | 74 KB |
| Search 10,000 vectors | 315 ms | 185 KB |
Brute-force search is O(n·d). Suitable for datasets up to ~100K vectors. Pair with an approximate index for larger scale.
Pure float32 math. No CGo, no syscalls, no I/O, no network. Every edge case returns zero/nil — the library never panics.
sync.Mutex.
One import. Zero dependencies.
go get github.com/BackendStack21/go-vector
go test github.com/BackendStack21/go-vector/pkg/vector/ -cover