perf: Avoid per-event heap allocation in SensorSetter#9579
Open
tomekzaw wants to merge 1 commit into
Open
Conversation
`sensorSetter` is invoked on every sensor sample (up to 60–200 Hz) and called `getRegion(0, size)`, which heap-allocates a `std::vector<jfloat>` each time. Read into a fixed stack buffer with the allocation-free `getRegion(start, length, buf)` overload instead. Also clamp the read to the fixed `array[7]` destination, removing the previous unchecked assumption that the Java array never exceeds 7 floats. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes the Android sensor callback path (SensorSetter::sensorSetter) by eliminating a per-sample heap allocation when reading FloatArray data from Java into C++, which is invoked at high frequency (60–200 Hz). It also adds a hard clamp to the destination buffer size (7), avoiding the previous unchecked assumption that the incoming array length never exceeds 7.
Changes:
- Replaces
getRegion(start, length)(allocatingstd::vector<jfloat>) with the allocation-freegetRegion(start, length, buf)overload. - Clamps the copied element count to a fixed maximum of 7 to match the native destination buffer.
- Adds
<algorithm>include forstd::min.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SensorSetter::sensorSetteris the Java→C++ callback invoked on every sensor sample (up to 60–200 Hz). It calledvalue->getRegion(0, size), which heap-allocates (the two-argumentgetRegionoverload returns astd::unique_ptr<jfloat[]>, i.e. anew jfloat[size]) on each invocation.This switches to the allocation-free
getRegion(start, length, buf)overload, reading directly into a fixed stack buffer — eliminating the per-event allocation:Why this reduces allocation: the win is heap vs. stack. The two-argument
getRegion(0, size)overload returns astd::unique_ptr<jfloat[]>— a heapnew[]/delete[](with allocator overhead) once per sensor event. The replacementjfloat elements[7]is an automatic stack array: no allocator involved, just a stack-pointer adjustment, essentially free. The extrajfloat[7]buffer exists only becausegetRegionyieldsjfloatwhile the callback wantsdouble; adding a stack buffer is free, removing the heap allocation is the gain. Net: one heap allocation per event → zero.As a side effect, the read is now clamped to the fixed
array[7]destination, removing the previous unchecked assumption that the incoming Java array never exceeds 7 floats.Behavior is otherwise unchanged.
Test plan
Run an example using
useAnimatedSensor(accelerometer / gyroscope / rotation) on Android and confirm sensor values flow through as before.