I'm trying to build an efficient scenario of checking one value for various cases, each case representing a different function needed to be executed. Specifically, I have a keypad matrix with function Buttons that all should provide different functions, but the code should execute in an efficient matter, so not waste much time on checking through each statement before reaching a conclusion.
Here's an example of what I'd like to do, but it still seems inefficient due to the lambda usage / lambda creation:
def data(value):
global combination
functions = {
'A' : print('Arm'),
'B' : pass,
'C' : lambda x: return False,
'D' : print('Disarm'),
'*' : lambda x: return x, #Asterisk=Enter
'#' : lambda x: x='', #Hashtag=InputCorrection
}(combination)
if type(value) is int:
##Collect numbers, irrelevant##
pass
if type(value) is str:
##Function Buttons##
return functions.get(value, 'Default = Ignore Input')
From my knowledge the fastest approach to this if-elif-else scenario is a dictionary, but correct me on that if I'm wrong.
I'm looking for a more efficient way than lambda x:
, since I've read that those lambda functions are generated on each call of the data(value)
function and thus consume time.
I require a time-efficient procedure since it should not slow down the process of detecting "Buttons being pressed" on the keypad.
Also note: It's not possible to have incorrect values, so there's no fall-through. Fall-throughs would be picked up before the provided function is even called, but generally speaking they are nonexistent in this scenario.
From my knowledge the fastest approach to this if-elif-else scenario is a dictionary
Don't assume, benchmark. The timeit
module is your friend.
I'm looking for a more efficient way than lambda x:, since I've read that those lambda functions are generated on each call of the data(value) function and thus consume time
That's true, but looking up a name in the global namespace also takes time.
Also note that the problem is not with lambdas per se, inner functions would exhibit the same problem - and while we're at it, if your lambdas are just calling another function (ie you have {"A": lambda x: funcA(x)}
), you don't even need the lambdas, just use {"A": funcA, "B": funcB, }
and you will save not only the lambda instanciation time but also (and that's more important) one function call with all the stack manipulations involved.
So once again, don't assume, benchmark.
Actually, before you even worry about benchmarking, check if there really is a performance issue, and then profile to find out where the bottleneck(s) is/are. We human are usually pretty bad at guessing this kind of things, and I've more than once seen developers wasting days "optimizing" the wrong parts of the code - making it unreadable and unmaintanable - without gaining any significative performance improvement, while using the profiler you could find a couple "quick wins" that took one day to implement, had no impact on readability, and dramaticallly improved the perfs (sometimes by an order of magnitude).
So back to your use case - you mainly have 3 possible implementations, a plain if/elif/, a local dict and a global dict. You can do a mock implementation of each solution and benchmark them using timeit
, and then you'll know which is the fastest for your python version. If you plan on supporting different Python versions make sure you repeat the test with all versions.