Python Code Optimization Techniques: Principles and Practical Tips
This article presents a comprehensive guide to speeding up Python programs by applying optimization principles, avoiding global variables and attribute look‑ups, reducing unnecessary abstractions and data copies, improving loop constructs, using built‑in functions like join, leveraging short‑circuit logic, and employing tools such as numba for JIT compilation.
Python is a high‑level scripting language that often lags behind compiled languages like C/C++ in raw performance, but many inefficiencies can be mitigated with careful coding. The article first outlines three core optimization principles: avoid premature optimization, weigh the cost of speed versus readability, and focus on the true bottlenecks.
0. Code‑Optimization Principles
Before diving into concrete tricks, developers are reminded to let code work correctly first, consider trade‑offs between time and space, and target only the slow parts—typically inner loops.
1. Avoid Global Variables
# 不推荐写法。代码耗时:26.8秒
import math
size = 10000
for x in range(size):
for y in range(size):
z = math.sqrt(x) + math.sqrt(y)Placing the logic inside a function reduces lookup time and yields a 15‑30% speed gain.
# 推荐写法。代码耗时:20.6秒
import math
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 Directly import functions to bypass module attribute look‑ups.
# 不推荐写法。代码耗时:14.5秒
import math
def computeSqrt(size: int):
result = []
for i in range(size):
result.append(math.sqrt(i))
return result
def main():
size = 10000
for _ in range(size):
result = computeSqrt(size)
main() # 第一次优化写法。代码耗时:10.9秒
from math import sqrt
def computeSqrt(size: int):
result = []
for i in range(size):
result.append(sqrt(i))
return result
def main():
size = 10000
for _ in range(size):
result = computeSqrt(size)
main()Assigning frequently used functions to local variables removes the extra dictionary lookup.
# 第二次优化写法。代码耗时:9.9秒
import math
def computeSqrt(size: int):
result = []
sqrt = math.sqrt
for i in range(size):
result.append(sqrt(i))
return result
def main():
size = 10000
for _ in range(size):
result = computeSqrt(size)
main()Further, caching list.append yields additional gains.
# 推荐写法。代码耗时:7.9秒
import math
def computeSqrt(size: int):
result = []
append = result.append
sqrt = math.sqrt
for i in range(size):
append(sqrt(i))
return result
def main():
size = 10000
for _ in range(size):
result = computeSqrt(size)
main()2.2 The same idea applies to class attributes.
# 不推荐写法。代码耗时:10.4秒
import math
from typing import List
class DemoClass:
def __init__(self, value: int):
self._value = value
def computeSqrt(self, size: int) -> List[float]:
result = []
append = result.append
sqrt = math.sqrt
for _ in range(size):
append(sqrt(self._value))
return result
def main():
size = 10000
for _ in range(size):
demo_instance = DemoClass(size)
result = demo_instance.computeSqrt(size)
main() # 推荐写法。代码耗时:8.0秒
import math
from typing import List
class DemoClass:
def __init__(self, value: int):
self._value = value
def computeSqrt(self, size: int) -> List[float]:
result = []
append = result.append
sqrt = math.sqrt
value = self._value
for _ in range(size):
append(sqrt(value))
return result
def main():
size = 10000
for _ in range(size):
demo_instance = DemoClass(size)
demo_instance.computeSqrt(size)
main()3. Avoid Unnecessary Abstraction
# 不推荐写法,代码耗时:0.55秒
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
def main():
size = 1000000
for i in range(size):
demo_instance = DemoClass(size)
value = demo_instance.value
demo_instance.value = i
main() # 推荐写法,代码耗时:0.33秒
class DemoClass:
def __init__(self, value: int):
self.value = value
def main():
size = 1000000
for i in range(size):
demo_instance = DemoClass(size)
value = demo_instance.value
demo_instance.value = i
main()4. Eliminate Redundant Data Copies
# 不推荐写法,代码耗时:6.5秒
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]
main() # 推荐写法,代码耗时:4.8秒
def main():
size = 10000
for _ in range(size):
value = range(size)
square_list = [x * x for x in value]
main()Swap without a temporary variable:
# 不推荐写法,代码耗时:0.07秒
def main():
size = 1000000
for _ in range(size):
a = 3
b = 5
temp = a
a = b
b = temp
main() # 推荐写法,代码耗时:0.06秒
def main():
size = 1000000
for _ in range(size):
a = 3
b = 5
a, b = b, a
main()5. Prefer str.join Over + for Concatenation
# 不推荐写法,代码耗时:2.6秒
import string
from typing import List
def concatString(string_list: List[str]) -> str:
result = ''
for str_i in string_list:
result += str_i
return result
def main():
string_list = list(string.ascii_letters * 100)
for _ in range(10000):
result = concatString(string_list)
main() # 推荐写法,代码耗时:0.3秒
import string
from typing import List
def concatString(string_list: List[str]) -> str:
return ''.join(string_list)
def main():
string_list = list(string.ascii_letters * 100)
for _ in range(10000):
result = concatString(string_list)
main()6. Use Short‑Circuit Logic in if Statements
# 不推荐写法,代码耗时:0.05秒
from typing import List
def concatString(string_list: List[str]) -> str:
abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'}
result = ''
for str_i in string_list:
if str_i in abbreviations:
result += str_i
return result
def main():
for _ in range(10000):
string_list = ['Mr.', 'Hat', 'is', 'Chasing', 'the', 'black', 'cat', '.']
result = concatString(string_list)
main() # 推荐写法,代码耗时:0.03秒
from typing import List
def concatString(string_list: List[str]) -> str:
abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'}
result = ''
for str_i in string_list:
if str_i[-1] == '.' and str_i in abbreviations:
result += str_i
return result
def main():
for _ in range(10000):
string_list = ['Mr.', 'Hat', 'is', 'Chasing', 'the', 'black', 'cat', '.']
result = concatString(string_list)
main()7. Loop Optimizations
Replace while with for loops.
# 不推荐写法。代码耗时:6.7秒
def computeSum(size: int) -> int:
sum_ = 0
i = 0
while i < size:
sum_ += i
i += 1
return sum_
def main():
size = 10000
for _ in range(size):
sum_ = computeSum(size)
main() # 推荐写法。代码耗时:4.3秒
def computeSum(size: int) -> int:
sum_ = 0
for i in range(size):
sum_ += i
return sum_
def main():
size = 10000
for _ in range(size):
sum_ = computeSum(size)
main()Use built‑in functions to hide the loop.
# 推荐写法。代码耗时:1.7秒
def computeSum(size: int) -> int:
return sum(range(size))
def main():
size = 10000
for _ in range(size):
sum = computeSum(size)
main()Cache expensive calls outside inner loops.
# 不推荐写法。代码耗时:12.8秒
import math
def main():
size = 10000
sqrt = math.sqrt
for x in range(size):
for y in range(size):
z = sqrt(x) + sqrt(y)
main() # 推荐写法。代码耗时:7.0秒
import math
def main():
size = 10000
sqrt = math.sqrt
for x in range(size):
sqrt_x = sqrt(x)
for y in range(size):
z = sqrt_x + sqrt(y)
main()8. JIT Compilation with numba
# 推荐写法。代码耗时:0.62秒
import numba
@numba.jit
def computeSum(size: float) -> int:
sum = 0
for i in range(size):
sum += i
return sum
def main():
size = 10000
for _ in range(size):
sum = computeSum(size)
main()9. Choose Appropriate Data Structures
Built‑in containers (list, dict, set, tuple) are implemented in C and are usually faster than custom structures. For frequent insert/delete at both ends, collections.deque offers O(1) operations. For fast ordered look‑ups, bisect on a sorted list or heapq for min/max retrieval are recommended.
References:
David Beazley & Brian K. Jones, Python Cookbook, Third edition , O'Reilly Media, 2013.
张颖 & 赖勇浩, 编写高质量代码:改善Python程序的91个建议 , 机械工业出版社, 2014.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
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.
