Python Code Optimization Techniques for Faster Execution
This article presents practical Python performance‑boosting techniques, covering fundamental optimization principles, avoiding global variables and unnecessary attribute access, reducing data copying, improving loop structures, leveraging short‑circuit logic, using numba JIT compilation, and selecting appropriate built‑in data structures to achieve significant speed gains.
Introduction
This article shares pure‑Python programming acceleration methods, explaining why Python, as an interpreted language, can be slower than compiled languages and providing concrete tips to improve execution speed.
0. Code Optimization Principles
Principle 1: Do not optimize prematurely; ensure code works correctly before measuring performance.
Principle 2: Weigh the cost of optimization; consider time‑space trade‑offs and development effort.
Principle 3: Focus on hot spots, typically inner loops, rather than optimizing every part of the code.
1. Avoid Global Variables
Placing code inside functions reduces lookup time for variables, yielding a 15‑30% speed improvement.
# Not recommended – global variables (26.8 s)
import math
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)
# Recommended – inside a function (20.6 s)
def main():
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)
main()2. Reduce Attribute Access
2.1 Avoid Module and Function Attribute Access
Importing specific functions (e.g., from math import sqrt ) eliminates the overhead of attribute lookups.
# Not recommended – attribute access (14.5 s)
import math
def compute_sqrt(size):
result = []
for i in range(size):
result.append(math.sqrt(i))
return result
# Recommended – local reference (10.9 s)
from math import sqrt
def compute_sqrt(size):
result = []
for i in range(size):
result.append(sqrt(i))
return result2.2 Avoid Class Attribute Access
Assign frequently used class attributes to local variables to avoid repeated self. lookups.
# Not recommended – class attribute (10.4 s)
class Demo:
def __init__(self, value):
self._value = value
def compute(self, size):
result = []
for _ in range(size):
result.append(math.sqrt(self._value))
return result
# Recommended – local variable (8.0 s)
class Demo:
def __init__(self, value):
self._value = value
def compute(self, size):
sqrt = math.sqrt
val = self._value
result = []
for _ in range(size):
result.append(sqrt(val))
return result3. Avoid Unnecessary Abstraction
Eliminate property getters/setters and decorators that add overhead when simple attributes suffice.
# Not recommended – property (0.55 s)
class Demo:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, x):
self._value = x
# Recommended – direct attribute (0.33 s)
class Demo:
def __init__(self, value):
self.value = value4. Avoid Unnecessary Data Copying
Do not create intermediate lists when a single comprehension suffices, and avoid deep copies unless required.
# Not recommended – extra list (6.5 s)
value = range(size)
value_list = [x for x in value]
square_list = [x*x for x in value_list]
# Recommended – single comprehension (4.8 s)
value = range(size)
square_list = [x*x for x in value]
# Swap without temporary variable (0.06 s)
a, b = b, a5. Leverage Short‑Circuit Logic
Place the most likely true condition first in or expressions and the most likely false condition first in and expressions to reduce evaluation cost.
# Recommended – short‑circuit (0.03 s)
if token[-1] == '.' and token in abbreviations:
result += token6. Loop Optimizations
6.1 Use for Instead of while
for loops are faster in CPython.
# Not recommended – while (6.7 s)
i = 0
while i < size:
sum_ += i
i += 1
# Recommended – for (4.3 s)
for i in range(size):
sum_ += i6.2 Implicit for Loops
Use built‑in functions like sum() that internally iterate.
# Recommended – implicit for (1.7 s)
def compute_sum(size):
return sum(range(size))6.3 Reduce Inner Loop Computations
Cache results of expensive operations outside inner loops.
# Not recommended – repeated sqrt (12.8 s)
for x in range(size):
for y in range(size):
z = sqrt(x) + sqrt(y)
# Recommended – cache sqrt(x) (7.0 s)
for x in range(size):
sqrt_x = sqrt(x)
for y in range(size):
z = sqrt_x + sqrt(y)7. Use numba.jit for JIT Compilation
Applying @numba.jit can dramatically speed up numeric loops.
# JIT‑compiled sum (0.62 s)
import numba
@numba.jit
def compute_sum(size):
total = 0
for i in range(size):
total += i
return total8. Choose Appropriate Data Structures
Prefer built‑in containers ( list , dict , set ) which are C‑implemented; for frequent insert/delete use collections.deque , for fast look‑ups use bisect , and for min/max retrieval use heapq .
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.