Skip to content

perf(random): Choice gathers without allocating per element - #115

Merged
tannevaled merged 2 commits into
mainfrom
perf/choice-gather
Nov 12, 2026
Merged

tannevaled merged 2 commits into
mainfrom
perf/choice-gather

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Generator.Choice, RandomState.Choice and random.Choice allocated twice per drawn element. The gather (takeAxis) sliced reflect.Values for every index, and each Value.Slice allocates. It now copies whole slabs through a byte view of the source and the result: one code path for all 13 dtypes, none of which hold pointers.

Closes #103

Allocations for 100 000 draws from a 1000-element array, from go test -run TestPerf -perf.record (exact under any load; docs/perf.json and docs/perf-table.md are updated):

row before after
random.Generator.Choice 200 013 13
random.RandomState.Choice 200 012 12
random.Choice 200 012 12

NumPy makes one allocation (the result); the 12–13 left are the fixed cost of the index draw and the result array. Timing is deferred: the 1-minute load here was 11, above the harness's limit of 8.

  • TestChoiceAllocsConstant: 100 and 10 000 draws must cost the same number of allocations, along axis 0 of a 1-D array and along axis 1 of a 2-D one. On the old code it fails with 213 vs 20 013 and 2 014 vs 200 014.
  • The values are unchanged: the NumPy golden tests in random/numpy_test.go pass.
  • random stays at 100 % statement coverage.
  • SECURITY.md: an audit-log entry for the unsafe.Slice view.

🤖 Generated with Claude Code

tannevaled and others added 2 commits November 12, 2026 12:09
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-D array

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 8ac94fb into main Nov 12, 2026
13 checks passed
@tannevaled
tannevaled deleted the perf/choice-gather branch November 12, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: random Choice allocates twice per drawn element (200 013 allocations for 100 000 draws)

1 participant