Python Code Optimization Techniques and Performance Tips
This article presents practical Python performance optimization techniques, covering principles such as avoiding premature optimization, reducing global variables, minimizing attribute access, eliminating unnecessary abstractions, avoiding data copying, using efficient string concatenation, leveraging short‑circuit logic, loop optimizations, JIT compilation with Numba, and selecting appropriate data structures.
Python is a scripting language that can be slower than compiled languages like C/C++, but many performance gaps can be narrowed with proper techniques. This article collects several practical Python code acceleration methods.
Code Optimization Principles
Before diving into details, understand three basic principles: do not optimize prematurely, weigh the cost of optimization, and focus on the parts of code that actually affect performance.
1. Avoid Global Variables
<code># Not recommended. Execution time: 26.8 seconds
import math
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)
</code>Placing code in the global scope incurs extra lookup overhead. Wrapping the logic in a function can improve speed by 15‑30%.
<code># Recommended. Execution time: 20.6 seconds
import math
def main():
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)
main()
</code>2. Avoid Module and Attribute Access
<code># First optimization. Execution time: 14.5 seconds
import math
def computeSqrt(size: int):
result = []
for i in range(size):
result.append(math.sqrt(i))
return result
</code>Importing specific functions reduces attribute lookups.
<code># Recommended. Execution time: 10.9 seconds
from math import sqrt
def computeSqrt(size: int):
result = []
for i in range(size):
result.append(sqrt(i))
return result
</code>3. Avoid Class Attribute Access
<code># Not recommended. Execution time: 10.4 seconds
class DemoClass:
def __init__(self, value: int):
self._value = value
def computeSqrt(self, size: int) -> List[float]:
result = []
for _ in range(size):
result.append(math.sqrt(self._value))
return result
</code>Accessing instance attributes inside tight loops is slower than using a local variable.
<code># Recommended. Execution time: 8.0 seconds
class DemoClass:
def __init__(self, value: int):
self._value = value
def computeSqrt(self, size: int) -> List[float]:
result = []
value = self._value
sqrt = math.sqrt
for _ in range(size):
result.append(sqrt(value))
return result
</code>4. Avoid Unnecessary Abstraction
<code># Not recommended. Execution time: 0.55 seconds
class DemoClass:
def __init__(self, value: int):
self.value = value
@property
def value(self) -> int:
return self._value
@value.setter
def value(self, x: int):
self._value = x
</code>Using property getters/setters adds overhead; simple attributes are faster.
<code># Recommended. Execution time: 0.33 seconds
class DemoClass:
def __init__(self, value: int):
self.value = value
</code>5. Avoid Unnecessary Data Copying
<code># Not recommended. Execution time: 6.5 seconds
def main():
size = 10000
for _ in range(size):
value = range(size)
value_list = [x for x in value]
square_list = [x * x for x in value_list]
</code>Creating intermediate lists wastes memory and time.
<code># Recommended. Execution time: 4.8 seconds
def main():
size = 10000
for _ in range(size):
value = range(size)
square_list = [x * x for x in value]
</code>6. Use join() Instead of + for String Concatenation
<code># Not recommended. Execution time: 2.6 seconds
def concatString(string_list: List[str]) -> str:
result = ''
for s in string_list:
result += s
return result
</code>Repeated '+' creates many intermediate strings. Using ''.join() allocates memory once.
<code># Recommended. Execution time: 0.3 seconds
def concatString(string_list: List[str]) -> str:
return ''.join(string_list)
</code>7. Leverage Short‑Circuit Evaluation of if
<code># Not recommended. Execution time: 0.05 seconds
def concatString(string_list: List[str]) -> str:
abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'}
result = ''
for s in string_list:
if s in abbreviations:
result += s
return result
</code>Placing the most likely true condition first reduces unnecessary checks.
<code># Recommended. Execution time: 0.03 seconds
def concatString(string_list: List[str]) -> str:
abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'}
result = ''
for s in string_list:
if s[-1] == '.' and s in abbreviations:
result += s
return result
</code>8. Loop Optimizations
Replace while loops with for loops for better performance.
<code># Not recommended. Execution time: 6.7 seconds
def computeSum(size: int) -> int:
sum_ = 0
i = 0
while i < size:
sum_ += i
i += 1
return sum_
</code> <code># Recommended. Execution time: 4.3 seconds
def computeSum(size: int) -> int:
sum_ = 0
for i in range(size):
sum_ += i
return sum_
</code>Use implicit for loops via built‑ins when possible.
<code># Recommended. Execution time: 1.7 seconds
def computeSum(size: int) -> int:
return sum(range(size))
</code>Move invariant calculations out of inner loops.
<code># Not recommended. Execution time: 12.8 seconds
for x in range(size):
for y in range(size):
z = sqrt(x) + sqrt(y)
</code> <code># Recommended. Execution time: 7.0 seconds
for x in range(size):
sqrt_x = sqrt(x)
for y in range(size):
z = sqrt_x + sqrt(y)
</code>9. Use numba.jit for JIT Compilation
<code># Recommended. Execution time: 0.62 seconds
import numba
@numba.jit
def computeSum(size: float) -> int:
sum = 0
for i in range(size):
sum += i
return sum
</code>10. Choose Appropriate Data Structures
Built‑in structures like list , dict , set are implemented in C and are fast. For frequent insert/delete at both ends, use collections.deque (O(1) operations). For fast ordered lookups, use bisect on a sorted list. For quick min/max access, use heapq to maintain a heap.
Overall, applying these principles can significantly reduce Python script execution time without sacrificing readability.
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.