2

I have a very large if/else block that that will be performing operations on a byte array. The id can technically be any number from 0x001 to 0xFFF, but they are generally known. each case is unique, and will perform calculations on different bytes in the array. the messages come from a queue at a rate of around .5ms - 1ms and get processed by this method

While the large if/else works, the biggest problem I see with it is that if, in this example, the id is 1222, we have to hit all of the previous ifs. Also as more messages are added the time complexity grows and it can get obnoxiously large.

def calcCanMessage(self):
    while: True
        #get msg - simplified for example
        msgId = msg.id
        msgData = msg.data
        if msgId == 324:
            #do something with msgData
            continue
        elif msgId == 211:
            continue
        elif msgId == 322:
            continue
        elif msgId == 321:
            continue
        elif msgId == 320:
            continue
        elif msgId == 342:
            continue
        elif msgId == 338:
            continue
        elif msgId == 24:
            continue
        elif msgId == 212:
            continue
        elif msgId == 323:
            continue
        elif msgId == 210:
            continue
        elif msgId == 209:
            continue
        elif msgId == 208:
            continue
        elif msgId == 642:
            continue
        elif msgId == 880:
            continue
        elif msgId == 1088:
            continue
        elif msgId == 865:
            continue
        elif msgId == 864:
            continue
        elif msgId == 882:
            continue
        elif msgId == 1595:
            continue
        elif msgId == 1090:
            continue
        elif msgId == 885:
            continue
        elif msgId == 884:
            continue
        elif msgId == 1224:
            continue
        elif msgId == 1761:
            continue
        elif msgId == 1762:
            continue
        elif msgId == 1245:
            continue
        elif msgId == 1219:
            continue
        elif msgId == 1217:
            continue
        elif msgId == 1222:
            continue
        else:
            print('unknown ID: ', msgId)

2 Answers2

2

First, define the functions that do (different) things with msgData. The function bodies will be whatever you're currently doing in each block of the if..else statement.

def msgId_324(msgData):
    #do something with msgData

def msgId_211(msgData):
    #do something else with msgData

# more functions to handle msgData

Then define a dictionary to pair all the message ID values with their corresponding function.

msgId_dict = {324: msgId_324, 
            211: msgId_211,
            # more msgId: msg_function pairs
            }

Now you can replace the if statement with a dictionary lookup, which will be much faster, no matter how many message values, and call the returned function.

msgId = msg.id
msgData = msg.data

if msgId in msgId_dict:
    msg_function = msgId_dict[msgId]
    msg_function(msgData)
else:
    # optional else case to handle unrecognized message IDs
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
2

As has been suggested in the comments, store the non-action msg ids in a set:

    ignore_messages = {211, 322, ..., 1222}

    msgId = msg.id
    msgData = msg.data
    if msgId == 324:
        # do something with msgData
    elif msgId not in ignore_messages:
        print('unknown ID: ', msgId)
user2390182
  • 72,016
  • 6
  • 67
  • 89