I am writing a script to capture message off a serial port, compare them against filters and pass them to the correct place if they match the filter. The program structure is to have a serial handling thread, a message handling thread and then allow engineers to write plugins to sit on top all of this. It all works great and is fast enough apart from comparing the filters (in honesty, even this is fast enough but it could be faster :p).
Message are decomposed by my program into objects with attributes (for example, the nature of the message). A filter is set by a plugin, and tells my program to test every message against the filter. If it matches, the plugin gets passed a copy of the message. Multiple filters can catch one message and filters "pass" if all of their attributes match the message- so a blank filter would pass all message, for example.
I currently keep a list of all filters that are active, and run each message by them one by one by passing them to a "sieve" function, which takes a message and a filter and returns true or false if it passes/doesn't pass.
Is there some way I speed my filtering system up? It gets called a huge number of times so any speed improvement would be great.
This is the function:
def sieve(message,thisFilter):
match = True
for condition in thisFilter:
#Only do something if all conditions in the filter match the object...
if condition == 'nature':
internalMatch = False
if message.nature == Data.natures[thisFilter[condition]]:
internalMatch = True
match &= internalMatch
elif condition == 'sender':
internalMatch = False
if message.sender == thisFilter[condition]:
internalMatch = True
match &= internalMatch
elif condition == 'receiver':
internalMatch = False
if message.receiver == thisFilter[condition]:
internalMatch = True
match &= internalMatch
elif condition == 'sequence':
internalMatch = False
if message.sequence == thisFilter[condition]:
internalMatch = True
match &= internalMatch
elif condition == 'isreply':
internalMatch= False
if message.nature == Data.natures["Ack"] or message.nature == Data.natures["Nack"]:
internalMatch = True
match &= internalMatch
if match:
#Message has passed filters. Return it, and the ID of the plugin that wants it
if thisFilter['transient']:
thisFilter['deleteme'] = True
return True
else:
return False