This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new e6615cb7 perf(internal/hashing): avoid boxing byte slices in
InsertOrGet (#1310)
e6615cb7 is described below
commit e6615cb75db5a5fef4510c936b6840f022b76cb3
Author: Minh Vu <[email protected]>
AuthorDate: Tue Sep 15 20:51:47 2026 +0200
perf(internal/hashing): avoid boxing byte slices in InsertOrGet (#1310)
## What changed
- `InsertOrGet` already receives a `[]byte`.
- It still called `getHash`, which accepts `interface{}` and boxed the
slice.
- This now calls `Hash(val, 0)` directly, matching the typed hashing
path.
- There is no behavior change.
## Benchmark
The focused `BenchmarkBinaryMemoTableInsertOrGet` exercises this exact
method with 65,536 lookups over 100 repeated values.
Apple M1 Pro, Go 1.26.3:
| | After |
| --- | ---: |
| ns/op | 1.28 ms |
| B/op | 0 |
| allocs/op | 0 |
The old Parquet byte-array benchmark was removed from this description
because it uses a separate memo implementation.
## Testing
- `go test ./internal/hashing`
- `go test ./...` with `PARQUET_TEST_DATA` configured
---
internal/hashing/xxh3_memo_table.go | 2 +-
internal/hashing/xxh3_memo_table_bench_test.go | 28 ++++++++++++++++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/internal/hashing/xxh3_memo_table.go
b/internal/hashing/xxh3_memo_table.go
index 0296f7d1..c30575e6 100644
--- a/internal/hashing/xxh3_memo_table.go
+++ b/internal/hashing/xxh3_memo_table.go
@@ -315,7 +315,7 @@ func (b *BinaryMemoTable) GetOrInsert(val interface{}) (idx
int, found bool, err
// it is inserted into the table. The return value 'found' indicates whether
the value
// was found in the table (true) or inserted (false) along with any possible
error.
func (b *BinaryMemoTable) InsertOrGet(val []byte) (idx int, found bool, err
error) {
- h := b.getHash(val)
+ h := Hash(val, 0)
p, found := b.lookup(h, val)
if found {
idx = int(p.payload.val)
diff --git a/internal/hashing/xxh3_memo_table_bench_test.go
b/internal/hashing/xxh3_memo_table_bench_test.go
index 87808a42..9054718e 100644
--- a/internal/hashing/xxh3_memo_table_bench_test.go
+++ b/internal/hashing/xxh3_memo_table_bench_test.go
@@ -143,3 +143,31 @@ func benchmarkBinaryMemoTableCopyOffsets(b *testing.B,
large, subset bool) {
})
}
}
+
+func BenchmarkBinaryMemoTableInsertOrGet(b *testing.B) {
+ const (
+ nunique = 100
+ nvalues = 1 << 16
+ )
+
+ values := make([][]byte, nvalues)
+ for i := range values {
+ values[i] = []byte(fmt.Sprintf("value-%08d", i%nunique))
+ }
+
+ table := hashing.NewBinaryMemoTable(nunique, nunique*16,
+ array.NewBinaryBuilder(memory.DefaultAllocator,
arrow.BinaryTypes.Binary))
+ defer table.Release()
+ for i := 0; i < nunique; i++ {
+ _, _, _ = table.InsertOrGet(values[i])
+ }
+
+ b.ReportAllocs()
+ b.SetBytes(int64(nvalues * len(values[0])))
+ b.ResetTimer()
+ for b.Loop() {
+ for _, value := range values {
+ _, _, _ = table.InsertOrGet(value)
+ }
+ }
+}