perflint¶
perflint is an extension for pylint for performance anti-patterns.
Installation¶
$ uv add --dev perflint
Use¶
… as an independent linter¶
$ uv run perflint src/
… as pylint plugin¶
$ uv run perflint src/ --load-plugins=perflint
… as pre-commit hook ~~~~~~~~~~~~~~~~~x~~~
perflint can also be used with the pre-commit framework:
repos:
- repo: https://github.com/tonybaloney/perflint
rev: 0.8.1
hooks:
- id: perflint
Rules¶
- W8101:
unnecessary-list-cast Unnecessary use of
list()on an already iterable type.- W8102:
incorrect-dictionary-iterator Incorrect iterator method for
dict: Python dictionaries store keys and values in two separate tables. They can be iterated separately. Using.items()and discarding either the key or the value with_is inefficient when.keys()or.values()can be used instead.- W8201:
loop-invariant-statement The loop is examined to determine statements or expressions whose result is constant on each iteration of a loop because they are based on named variables that are not changed during the iteration.
- W8202:
loop-global-usage Global name usage in a loop: loading global variables is slower than loading local variables. The difference is marginal, but when passed in a loop, there can be a noticeable speed improvement.
- R8203:
loop-try-except-usage Up until Python 3.10,
try…exceptblocks are very computationally intensive compared toifstatements.Avoid using them in a loop as they can cause significant overhead. Refactor your code so that no iteration-specific details are required and put the entire loop in the
tryblock.- W8204:
memoryview-over-bytes Slicing byte objects in loops is inefficient because it creates a copy of the data. Use
memoryview()instead.- W8205:
dotted-import-in-loop Direct import of the name
%sis more efficient in a loop. In Python, you can import a module and then access submodules as attributes. You can also access functions as attributes of that module. This keeps the import statements to a minimum. However, if you use this method in a loop, it is inefficient because each loop pass loads the global, then the attribute, then the method.- W8301:
use-tuple-over-list Use a tuple instead of a list for an immutable sequence: both the construction and indexing of a tuple is faster than that of a list.
- W8401:
use-list-comprehension Use list comprehensions with or without an
ifstatement instead of aforloop.- W8402:
use-list-copy Use
list.copy()instead of aforloop.- W8403:
use-dict-comprehension Uses a dictionary comprehension instead of a simple
forloop.