Cleanest way to implement optimized and non-optimesed versions of a function?

Viewed 61

for a university project I want to implement some code in python. Later on, parts of it should be replaced with calls to native CUDA code.

Right now, I was thinking about putting a module wide switch OPTIMIZED in my module.

def set_optimized(b):
    # possible check for CUDA device first
    OPTIMIZED = b

def my_fun(arg1, arg2):
    if OPTIMIZED:
       # some c-calls here
       return retval
    else:
       # some python code here
       return retval

This implementation has some nice properties:

  • Test cases can easily compare optimized and non-optimized versions in result & performance.
  • For every optimized function there is a non-optimized backup. For example on machines without CUDA device, I suppress the switch to the optimized version and the programm still runs without changes to the code.

Another option would be to implement all functions as methods of a class NonOpt. The functions could be overriden with optimized versions in class Opt(NonOpt). It feels like this option has less boilerplate code, but comes with a disadvantage: the algorithm which instantiate and use the class has to be aware of the underlying opt/nonopt versions.

Is there a canonical way to do this? Or is it a bad idea anyway and I'm overlooking something fundamental?

Sidenote: To me this question is quite general. I've stumbled over this problem in the past, when I wanted to maintain optimized and non-optimized code in Julia. Whenerver I had to change the math, I could simply change the easy-readable non-optimized version. The testcases would tell me, wether I've achived the same results in the more complicated optimized version.

1 Answers

Adding another option to your list and to possibly "segregate" your functions is using if statement during import. Depends on your style, just make sure they will end up with the same name and contains the same function names.

if OPTIMIZED:
    from optimized import mymodule
else:
    from non_optimized import mymodule

Another method is called monkey-patching (replacing the imported methods during runtime).

Related