bits-and-blooms / bloom

Go package implementing Bloom filters, used by Milvus and Beego.
BSD 2-Clause "Simplified" License
2.44k stars 232 forks source link

Reduce allocations on string operations #93

Open KimMachineGun opened 1 year ago

KimMachineGun commented 1 year ago

For now, *String methods are just syntactic sugars for []byte(str) conversion; thus, they make unnecessary allocations and copies. This change optimizes string operations not to make any allocations and (data) copies.

Below is benchstat result: (it would make bigger improvements on the longer key)

goos: darwin
goarch: arm64
pkg: github.com/bits-and-blooms/bloom/v3
                            │   old.txt    │              new.txt               │
                            │    sec/op    │   sec/op     vs base               │
SeparateTestAndAddString-10   314.1n ±  1%   294.8n ± 3%  -6.18% (p=0.001 n=10)
CombinedTestAndAddString-10   305.5n ± 11%   281.8n ± 8%  -7.76% (p=0.004 n=10)
geomean                       309.8n         288.2n       -6.97%

                            │  old.txt   │                new.txt                │
                            │    B/op    │   B/op    vs base                     │
SeparateTestAndAddString-10   224.0 ± 0%   0.0 ± 0%  -100.00% (p=0.000 n=10)
CombinedTestAndAddString-10   112.0 ± 0%   0.0 ± 0%  -100.00% (p=0.000 n=10)
geomean                       158.4                  ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

                            │  old.txt   │                 new.txt                 │
                            │ allocs/op  │ allocs/op   vs base                     │
SeparateTestAndAddString-10   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
CombinedTestAndAddString-10   1.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
geomean                       1.414                    ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

FYI. I didn't use unsafe.Slice (introduced in Go 1.17) in this change to support older versions.