I’ve found myself on several occasions wanting a safe-but-slow version as well as an unsafe-but-fast version of a function.
@inbounds solve this problem marvelously for array indexing, but that’s not exactly what I need this for.
Here are two example scenarios, along with the current, hacky solutions from RigidBodyDynamics.jl:
- Frame checks. A common source of errors in kinematics/dynamics code is coordinate frame mismatches. I try to eliminate this class of errors by checking that frames match before performing operations. I do this using an @framecheck macro (example usage). To elide the frame checks when maximal performance is desired, I abuse the
@framecheck, as was rightfully pointed out during Juliacon: running Julia with
--check-bounds=nowill also elide the frame checks.
- Cache checks. To prevent doing double work, I store intermediate results in
CacheElements, which store data along with a
dirtyflag. Ideally, the value of the
dirtyflag should always be checked before accessing the data stored in a
CacheElement, but that has too much overhead in general, so I need a user-friendly way to elide those checks when it is known that the cache is up to date. I hacked together an
@nocachecheckmacro (example usage) that replaces calls to a short list of functions with calls to unsafe methods of those functions.
The first of these solutions is of course undesirable because it conflates two different types of checks. The second is undesirable because it is not possible to differentiate between calls to different methods of the same function (except by the number of arguments) in a macro.
Unfortunately, exactly replicating the
@inbounds machinery requires hooks into the compiler.
So, I’m wondering:
- is there a better way to replicate the bounds checking behavior without hooks into the compiler?
- if the answer to the first question is no, would it be feasible and desirable to generalize the bounds checking hooks in the compiler to make it easy to set up new sets of macros similar to
@propagate_inbounds), but for a different purpose and with separate on/off switches?