On Sat, 30 Jul 2016 06:32 pm, Johannes Bauer wrote: > Hi group, > > I'm using CPython 3.5.1. Currently I'm writing some delicate code that > is doing the right thing in 99% of the cases and screws up on the other > 1%. > > I would like to have tracing in some very inner loops: > > if self._debug: > print("Offset %d foo bar" % (self._offset)) > > However, this incurs a hefty performance penalty even when tracing > disabled.
Without seeing your code, it's hard to say. My guess is that you can optimize this slightly: class X: def method(self): debug = bool(self._debug) # force a bool, just in case for value in sequence: # critical loop if debug: print("Offset %d foo bar" % (self._offset)) ... That saves an attribute lookup and *potentially* a bool conversion each time around the loop. If that's still too slow, just about the fastest thing you can do is Python is an "is" comparison against None. Try this: class X: def method(self): if self._debug: sentinel = None else: sentinel = object() # Anything except None. for value in sequence: # critical loop if sentinel is None: print("Offset %d foo bar" % (self._offset)) ... Of course, it's even faster to NOT do a comparison: class X: def method(self): if self._debug: for value in sequence: # critical loop print("Offset %d foo bar" % (self._offset)) ... else: for value in sequence: # critical loop ... although that duplicates code. If the body of the loop is only small, say two or three lines at most, you might not mind that it is duplicated. > What I want is that the if clause completely disappears during bytecode > compilation if self._debug is not set. Is there any way that I can tell > the optimizer that this variable will either be set once, but never > change during runtime and that it can go ahead and completely remove the > code when self._debug is False? No. However, you can get a similar result using the magic dunder variable __debug__ (that's TWO leading and trailing underscores): class X: def method(self): for value in sequence: # critical loop if __debug__: print("Offset %d foo bar" % (self._offset)) ... In that case, the byte-code generated will be equivalent to the critical loop: for value in sequence: # critical loop print("Offset %d foo bar" % (self._offset)) ... with no test, unless you pass -O as a command-line option to Python, in which case both the test and the call to print will be completely removed: for value in sequence: # critical loop ... -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list