I am using such constructs to test whether a needed key is pressed:
def eventFilter(self, tableView, event):
if event.type() == QtCore.QEvent.KeyPress:
key = event.key()
if event.modifiers() in (QtCore.Qt.NoModifier, QtCore.Qt.KeypadModifier):
if key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.menu.editItem.trigger()
return True
I know that ‘Premature optimization is the root of all evil’, but i think eventFilter is called quite often to think about its optimization.
My concerns:
if key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return)upon each run makes double lookup: 1. FindQtattribute inQtCoremodule; 2. FindKey_Enterattribute inQtmodule.if key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return)this constructs the tuple upon each run. The search in the tuple is sequential – better to usefrozenset?
How do you deal with such cases? Don’t care?
Your code:
As I mentioned in a comment to @interjay, there may be a multitude of calls to this function for any kind of UI event, and if you have many of these filters, they could make for a sluggish UI. If you wanted to optimize this at least as far as the first if test, then move the local definition of
QtCore.QEvent.KeyPressinto a default argument value:(I also moved the function call to event.key() to after the test on event.modifiers().)
Default arguments like this are evaluated once at function compile time when the module is imported, not once per call, so your lookups for
QtCore.QEvent.KeyPresswill be accelerated. You could of course take this to the extreme of:Now you have optimized not only the module-object-attribute lookups, but also the tuple constructions, and as @AndrewDalke mentions, my testing of
inshows it is faster for tuples than sets up to a size of about 3 or 4 elements. The single condition will still short-circuit when any part of the condition fails, so you won’t get calls to event.modifiers or event.key if the type is not a keypress.EDIT: I like @ekhumoro’s coupled testing of key and modifier, here’s how it would look merged into my code: