Switch find_first_continuous_callback to use a generated implementation. #920
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
As mentioned in SciML/DifferentialEquations.jl#971, the current recursive method for identifying the first continuous callback can cause the compiler to give up on type inference, especially when there are many callbacks. The fallback then allocates.
This switches this function to using a generated function (along with an inline function that takes splatted tuples). Because this generated function explicitly unrolls the tuple, there are no type inference problems.
Testing
I added a test that allocates using the old implementation (about 19kb allocations!) but does not with the new function. If I remove one of the callbacks, the allocations no longer happen with the recursive function, so it might be dependent on e.g. the specific Julia version to determine the point where the compiler gives up on type inference.
It passes all of the other DiffEqBase.jl, but I was wondering if there was a better test suite I could do to ensure this is working as expected. It seems to work in my ODE code, but I'm a little wary since I touched some pretty core code.