Skip to content

Commit c27ed14

Browse files
authored
chore: Simplify and optimize interpolate implementation (#8397)
## Summary The previous implementation unnecessarily used the `O(n)` loop to find the current interpolation value instead of using a simple binary search. It also Used unnecessary check if length of the input range is greater than 2 as this case doesn't have to be handled separately.
1 parent 40e3931 commit c27ed14

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

packages/react-native-reanimated/src/interpolation.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -191,29 +191,35 @@ export function interpolate(
191191

192192
const extrapolationConfig = validateType(type);
193193
const length = inputRange.length;
194-
const narrowedInput: InterpolationNarrowedInput = {
195-
leftEdgeInput: inputRange[0],
196-
rightEdgeInput: inputRange[1],
197-
leftEdgeOutput: outputRange[0],
198-
rightEdgeOutput: outputRange[1],
199-
};
200-
if (length > 2) {
201-
if (x > inputRange[length - 1]) {
202-
narrowedInput.leftEdgeInput = inputRange[length - 2];
203-
narrowedInput.rightEdgeInput = inputRange[length - 1];
204-
narrowedInput.leftEdgeOutput = outputRange[length - 2];
205-
narrowedInput.rightEdgeOutput = outputRange[length - 1];
206-
} else {
207-
for (let i = 1; i < length; ++i) {
208-
if (x <= inputRange[i]) {
209-
narrowedInput.leftEdgeInput = inputRange[i - 1];
210-
narrowedInput.rightEdgeInput = inputRange[i];
211-
narrowedInput.leftEdgeOutput = outputRange[i - 1];
212-
narrowedInput.rightEdgeOutput = outputRange[i];
213-
break;
214-
}
194+
let narrowedInput: InterpolationNarrowedInput;
195+
196+
if (x > inputRange[length - 1]) {
197+
narrowedInput = {
198+
leftEdgeInput: inputRange[length - 2],
199+
rightEdgeInput: inputRange[length - 1],
200+
leftEdgeOutput: outputRange[length - 2],
201+
rightEdgeOutput: outputRange[length - 1],
202+
};
203+
} else {
204+
let left = 1;
205+
let right = length - 1;
206+
207+
while (left < right) {
208+
const mid = Math.floor((left + right) / 2);
209+
if (x <= inputRange[mid]) {
210+
right = mid;
211+
} else {
212+
left = mid + 1;
215213
}
216214
}
215+
216+
const segmentIndex = left;
217+
narrowedInput = {
218+
leftEdgeInput: inputRange[segmentIndex - 1],
219+
rightEdgeInput: inputRange[segmentIndex],
220+
leftEdgeOutput: outputRange[segmentIndex - 1],
221+
rightEdgeOutput: outputRange[segmentIndex],
222+
};
217223
}
218224

219225
return internalInterpolate(x, narrowedInput, extrapolationConfig);

0 commit comments

Comments
 (0)