I’m writing a relatively straight-forward physics simulation, in which many small indicator points are initialized. The core of the code is in one project, with two different interface projects (i.e. two solutions) both using the same core.
The indicator points are instances of a class, Point
, which is itself inherited by several other classes (to allow new properties and physics to be considered). Each Point
has a location (x,y,z) and a The fundamental method in Point
is Advance
, which calculates the location update using the Runge-Kutta 4th-order (RK4) method. With many points this can become quite expensive, so for debugging and experimentation purposes I want to be able to switch to a lower-order method (e.g. simple first-order Euler integration, or perhaps a predictor-corrector method).
My question is: what is the most efficient way to handle this situation?
I’ve so far thought of three solutions:
- Option 1: Declare a bool
EulerUpdate
at program initiation which is passed to thePoint
constructor (and of course to the constructor of all inheriting classes). This can then be used in one of two ways:- Option 1a: Set a private bool in the class, say
UseEuler
. WithinAdvance
, check ifUseEuler
is true; if so, run the faster code. If false, use the slower, more accurate RK4 code. - Option 1b: Set a private function in the class, say
UpdateCalc
. Within the constructor, setUpdateCalc
to either a method representing the Euler integration method (e.g.UpdateCalc = EulerUpdate
) or the RK4 integration method (UpdateCalc = RK4Update
) depending on the value ofEulerUpdate
. InAdvance
, just callUpdateCalc
.
- Option 1a: Set a private bool in the class, say
- Option 2: Use preprocessor directives in
Advance
(i.e.#if EULERINTEGRATION
) and then declare those in thecsproj
.
The problems I have with each are as follows:
- Option 1: Both of these seem like they’ll be slow because they involve either a) putting an if statement in very low-level code or b) doing some runtime shenanigans (polymorphism? I guess?). However, I do not know anywhere near enough about performance (in particular, performance in C#) to be able to comment sensibly.
- Option 2: While this seems guaranteed to be the most efficient option, it comes with the problem that it would mean I have to recompile the core library for each interface. I’m reluctant to take that hit if I don’t have to.
I’d be grateful to hear your perspectives on this; I’ve tried option 1 and found that it provided a serious benefit in run time, but I’m hopeful that I might both be able to do something better and to learn something more fundamental about writing efficient code at the same time. Thanks!