Home / Python / Day 10: Advanced Python / Python Performance Optimization

Python Performance Optimization

Writing efficient Python code involves choosing the right data structures, avoiding unnecessary work, and measuring performance before optimizing.

Measure Before Optimizing

"Premature optimization is the root of all evil." Always profile your code first to find actual bottlenecks using tools like the time module, timeit, or the cProfile module — don't guess.

Choosing the Right Data Structure

Use the right tool for the job: lists for ordered collections, sets for fast membership testing (in is O(1) for sets vs O(n) for lists), dictionaries for key-based lookups, and tuples for fixed, immutable data.

Avoiding Unnecessary Work

Avoid repeated computation inside loops — calculate values once outside the loop if they don't change. Avoid building large intermediate lists when a generator would do.

List Comprehensions vs Loops

List comprehensions are often faster than equivalent for-loops with .append() because they are optimized internally by the interpreter.

String Concatenation

Repeatedly concatenating strings with + in a loop is slow because strings are immutable (each concatenation creates a new string). Use "".join(list_of_strings) instead.

Using Built-in Functions and Libraries

Built-in functions (sum(), max(), sorted()) and libraries like NumPy are implemented in C and are usually much faster than hand-written Python loops for the same task.

Caching with functools.lru_cache

For expensive functions called repeatedly with the same arguments, @functools.lru_cache caches results automatically, avoiding redundant computation.