base64
drop-in
encoding/base64
encode ~17ร stdlib; beats emmansun/base64 ~5โ6% (cycle-model-guided).
LICENSE=BSD-3-ClauseCGO_ENABLED=0Pure-Go SIMD drop-ins for the standard library โ
base64, base32, hex, ascii85,
utf8, adler32, crc32, crc64,
strconv and the primitives under them, with byte-identical
output on plain go build.
$ go get github.com/go-simd/base64@latest $ go get github.com/go-simd/base32@latest $ go get github.com/go-simd/hex@latest $ go get github.com/go-simd/utf8@latest $ go get github.com/go-simd/adler32@latest $ go get github.com/go-simd/strconv@latest
Each package is a drop-in: the same signatures and
byte-identical output (and errors) as the stdlib package it accelerates.
The hot loop is real SIMD assembly emitted by
go-asmgen (v0.5.0) for
all six 64-bit Go targets — amd64, arm64, riscv64, loong64,
ppc64le (VSX) and s390x (vector facility, big-endian) —
and encoded by cmd/asm; the short tail delegates back to the standard library so
results match exactly. The numbers are measured and honest โ wins, parities,
and the cases where SIMD genuinely does not help.
Six architectures, one generator. The amd64/arm64 throughput
figures below are native measurements. Most repos are now measured on real IBM z15
(VXE2, native execution, 2026-07-03, -count=6) — the vector-facility kernels
post clear wins (e.g. bitpack ~34×, streamvbyte decode ~20×,
hex encode ~18×, matchlen ~9.2×,
crc64 ~9.1×) and are bit-exact on big-endian
(jsonvalidate and ascii85 still await a follow-up z15 run).
ppc64le kernels are measured on real POWER9 where a GCC Compile Farm runner is
available, otherwise qemu-validated for correctness. Two highlights:
base32 gets real SIMD on ppc64le (VSRH) and s390x
(VMLHH) precisely where Go's arm64 assembler lacks the register-variable shift and
integer vector multiply it needs; and every kernel is byte-for-byte correct on big-endian
s390x.
Beyond these six native targets, matchlen-wasm is a
proof-of-concept 7th target — wasm-SIMD (v128) —
callable from browsers and WASI hosts via //go:wasmimport, since the Go compiler
does not emit v128 from Go source. It is a standalone companion repo, not one of
the 21 packages below.
highway is a
maintained fork of ajroetker/go-highway,
not a go-asmgen package: its upstream releases require a tool module at a version that was never
published, so no consumer could go mod tidy against them. The fork publishes that module,
retracts the inherited broken tags and carries security updates until upstream releases the fix.
On amd64 its AVX2/AVX-512 kernels need GOEXPERIMENT=simd; without it, integer kernels
take an allocating generic fallback — measure before you rely on it.
base64
drop-inencoding/base64
encode ~17ร stdlib; beats emmansun/base64 ~5โ6% (cycle-model-guided).
base32
drop-inencoding/base32
encode ~7.9ร stdlib (AVX2), SIMD decode too, and arm64 NEON encode + decode (decode ~25ร at 1 MiB). Real SIMD on ppc64le VSRH + s390x VMLHH; ppc64le measured on real POWER9 (decode ~5.5ร). No prior pure-Go SIMD base32.
hex
drop-inencoding/hex
beats tmthrgd/go-hex both ways โ encode 20.4ร, decode 6.24ร stdlib.
utf8
drop-inunicode/utf8
Valid ~19ร stdlib, edges stuartcarnie/go-simd ~3.5% (Lemire/Keiser).
adler32
drop-inhash/adler32
~12โ14ร stdlib, but ~7% behind mhr3/adler32-simd โ near-parity, honest.
strconv
drop-instrconv (base-10 parse + ParseFloat)
ParseInt/Atoi ~2.2โ2.7ร on long inputs; added SIMD ParseFloat (Eisel-Lemire, ~1.1โ1.36ร); never regresses (delegates short/uncertain).
matchlen
primitiveLZ match-finder primitive
~10ร scalar (NEON); real SIMD on all 6 arches; AVX2 ~2.08ร SSE2. Measured native: ppc64le POWER9 ~6.3ร, riscv64 X60 ~5.8ร, loong64 ~11.4ร scalar.
matchlen-wasm
proof of conceptthe 7th target: GOOS=js/wasip1 GOARCH=wasm
Go emits no v128 from source and wasm has no Plan 9 asm dialect, so a naive wasm build of matchlen falls back to scalar. The kernel lives in a companion module compiled from matchlen.wat and is called through //go:wasmimport. Measured on wazero 1.12.0 it is SLOWER below 4 KiB โ 0.16x scalar at 64 B, 0.94x at 1 KiB โ crosses over at 4 KiB (1.19x) and reaches 1.43x at 64 KiB. The call boundary is the cost, which is why this is a proof of concept and not the default path.
bitpack
primitiveFastPFOR / simdcomp bit-packing
~21โ32ร scalar โ byte-exact vs Lemire's simdcomp. ppc64le measured on real POWER9: Pack ~7.0ร, Unpack ~11.3ร (overturns the earlier ~1.1ร llvm-mca estimate).
popcount
primitiveHamming weight over []byte
size-dependent: ~9โ12ร in-cache, converges to memory-bound out-of-cache. Measured native: loong64 LSX ~6.1ร, ppc64le POWER9 ~2.9ร scalar (riscv64 stays scalar โ no per-element vector popcount in Go's RVV asm).
histogram
primitivebyte-value histogram
multi-table scalar โ measured, SIMD does NOT help (no scatter on AVX2/NEON).
crc64
drop-inhash/crc64
first pure-Go SIMD crc64 (stdlib + all Go libs are scalar); CLMUL folding, arm64 ~4.2ร stdlib; all 6 arches (riscv64/loong64 scalar).
crc32
drop-inhash/crc32
arm64-only, deliberately: stdlib IEEE path is already hardware-assisted on amd64/ppc64le/s390x, so only arm64's serial CRC32X fallback is worth beating; PMULL/PMULL2 fold-by-eight does that, every other arch and non-IEEE polynomial just calls hash/crc32.
ascii85
drop-inencoding/ascii85
first SIMD ascii85, SIMD encode AND decode; real SIMD on all 6 arches incl. an arm64 NEON kernel on Go 1.27. Measured native: ppc64le POWER9 ~2.9ร encode, riscv64 X60 ~4.0ร, loong64 ~4.3ร; arm64 NEON ~3.0ร / fused-scalar ~1.9ร on stable Go.
floats
primitiveDot/Sum/Min/Max/Distance/CosineSimilarity (float32 + float64); Axpy/Xpby/AxpyDot/Scale (float64)
only pure-Go lib with the full vector-search API on all 6 arches (gonum/vek/kelindar are amd64-centric or partial); arm64 ~2ร scalar. Since v0.4.0 the BLAS-1 updates Axpy/Xpby/AxpyDot/Scale, bit-identical to math.FMA on every arch: AVX2 3.0โ7.7ร, M4 NEON 1.6โ5.3ร over the scalar loop at n=1e3โ1e6. ppc64le measured on real POWER9: f32 VSX kernel ~1.55โ1.61ร over naive, f64 routes to the gc-autovectorized scalar loop (it beats VSX there โ honest).
xxhash
primitiveXXH3-64
first Go XXH3 on all 6 SIMD arches, bit-exact vs official vectors. Honest: zeebo faster on arm64 (~22 vs ~15 GB/s), amd64 block-at-a-time kernel reaches ~0.94ร zeebo. Where zeebo has no kernel we win big: riscv64 RVV ~2.5โ3.5ร zeebo on real X60 silicon; ppc64le near-parity (~0.91ร) on real POWER9.
streamvbyte
primitiveStream VByte uint32 codec
first Go port on all 6 arches (others amd64-only); full codec โ SIMD encode and decode, byte-identical to lemire/streamvbyte; decode arm64 ~10ร scalar. Measured native: ppc64le POWER9 decode ~11.6ร, riscv64 X60 ~4.5ร, loong64 ~11.8ร scalar.
ascii
drop-inASCII case (ToUpper/ToLower/EqualFold)
branchless vector case-fold, byte-identical to bytes/strings; real SIMD on all 6 arches incl. arm64 (multiply-free sign-bit predicate); arm64 ~4.9ร stdlib (ToUpper).
levenshtein
primitiveedit distance (Distance)
Myers bit-parallel edit distance, 62โ142ร vs agnivade/levenshtein on long inputs. Honest: pure-Go bit-parallel, not vector-SIMD (word-serial column, no lane parallelism); endian-clean on all 6 arches.
bitset
primitivebulk []uint64 set ops
SIMD And/Or/AndNot/Xor + fused Count/IntersectionCount; amd64 Count ~3โ3.9ร. Honest: logical ops are bandwidth-bound (converge to scalar out-of-cache), popcount wins across the board.
int8dot
primitiveint8 quantized dot (Dot/DotUint8/DotU8S8)
INT8 multiply-accumulate for ML embeddings, bit-exact vs scalar; amd64 AVX2 ~4ร; arm64 NEON kernel on Go 1.27 (~2.4ร; scalar on stable Go โค 1.26). Measured native: riscv64 X60 ~9.1ร (biggest RVV win in the suite), loong64 ~8.9ร (DotUint8 ~13.8ร), ppc64le POWER9 ~4.1ร.
jsonvalidate
drop-inencoding/json.Valid
byte-identical verdict to encoding/json.Valid; only SIMD JSON validator on all 6 arches (simdjson-go is amd64-only); SIMD string/space scans, ~1.4ร on string-heavy JSON (number-/structure-heavy stays scalar). Measured native on string-heavy: ppc64le POWER9 ~8.5ร stdlib, riscv64 X60 ~5.2ร.
Every kernel is generated by go-asmgen (v0.5.0) over a shared ABI0 layout
(amd64 SSE2/AVX2, arm64 NEON, loong64 LSX/LASX, riscv64 RVV, ppc64le VSX, s390x vector
facility), cycle-modelled with llvm-mca, validated on real AVX2 / native arm64 /
QEMU riscv64+loong64+ppc64le+s390x, and held at 100% statement coverage as a CI gate. The
headline benchmarks come from native CI; s390x is measured on real IBM z15
(VXE2, 2026-07-03) and ppc64le on real POWER9 where a GCC Compile Farm runner is available.