Python性能优化技巧
2026/5/15 0:57:54 网站建设 项目流程

Python性能优化技巧

一、性能分析工具

在优化之前,首先要找出性能瓶颈。

1.1 使用timeit测量执行时间

import timeit

# 测量代码片段执行时间
code = """
result = sum(range(1000))
"""

time = timeit.timeit(code, number=10000)
print(f"执行时间: {time:.4f}秒")

# 比较不同实现
time1 = timeit.timeit('"-".join(str(i) for i in range(100))', number=10000)
time2 = timeit.timeit('"-".join([str(i) for i in range(100)])', number=10000)
time3 = timeit.timeit('"-".join(map(str, range(100)))', number=10000)

print(f"生成器: {time1:.4f}秒")
print(f"列表推导: {time2:.4f}秒")
print(f"map: {time3:.4f}秒")

1.2 使用cProfile进行性能分析

import cProfile
import pstats

def slow_function():
total = 0
for i in range(1000000):
total += i
return total

# 分析函数性能
cProfile.run('slow_function()', 'profile_stats')

# 查看统计信息
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10)

1.3 使用line_profiler逐行分析

# 安装: pip install line_profiler
# 使用装饰器标记要分析的函数
@profile
def function_to_profile():
a = [i for i in range(10000)]
b = [i**2 for i in a]
return sum(b)

# 运行: kernprof -l -v script.py

二、数据结构选择

选择合适的数据结构对性能影响巨大。

2.1 列表 vs 集合

# 检查元素是否存在
import time

# 列表(O(n))
large_list = list(range(10000))
start = time.time()
9999 in large_list
print(f"列表查找: {time.time() - start:.6f}秒")

# 集合(O(1))
large_set = set(range(10000))
start = time.time()
9999 in large_set
print(f"集合查找: {time.time() - start:.6f}秒")

2.2 列表 vs 双端队列

from collections import deque

# 列表在头部插入很慢(O(n))
lst = []
for i in range(10000):
lst.insert(0, i)

# 双端队列在头部插入很快(O(1))
dq = deque()
for i in range(10000):
dq.appendleft(i)

2.3 字典 vs defaultdict

from collections import defaultdict

# 普通字典
word_count = {}
for word in ['apple', 'banana', 'apple']:
if word not in word_count:
word_count[word] = 0
word_count[word] += 1

# defaultdict更简洁高效
word_count = defaultdict(int)
for word in ['apple', 'banana', 'apple']:
word_count[word] += 1

三、避免不必要的计算

3.1 缓存计算结果

from functools import lru_cache

# 不使用缓存
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)

# 使用缓存
@lru_cache(maxsize=None)
def fibonacci_cached(n):
if n < 2:
return n
return fibonacci_cached(n-1) + fibonacci_cached(n-2)

# fibonacci(35) 很慢
# fibonacci_cached(35) 很快

3.2 避免重复计算

# 低效
def process_data(data):
for item in data:
if len(data) > 100: # 每次都计算len(data)
process_large(item)

# 高效
def process_data(data):
data_len = len(data) # 只计算一次
for item in data:
if data_len > 100:
process_large(item)

四、字符串操作优化

4.1 字符串拼接

# 低效:使用+拼接
result = ""
for i in range(10000):
result += str(i)

# 高效:使用join
result = "".join(str(i) for i in range(10000))

# 高效:使用列表累积
parts = []
for i in range(10000):
parts.append(str(i))
result = "".join(parts)

4.2 字符串格式化

name = "Alice"
age = 30

# 较慢
s1 = "Name: %s, Age: %d" % (name, age)

# 较快
s2 = "Name: {}, Age: {}".format(name, age)

# 最快
s3 = f"Name: {name}, Age: {age}"

五、列表推导式 vs 循环

# 循环
squares = []
for i in range(1000):
squares.append(i**2)

# 列表推导式(更快)
squares = [i**2 for i in range(1000)]

# 生成器表达式(内存效率更高)
squares = (i**2 for i in range(1000))

六、使用内置函数和库

内置函数通常用C实现,比纯Python代码快得多。

# 慢
def my_sum(numbers):
total = 0
for num in numbers:
total += num
return total

# 快
total = sum(numbers)

# 慢
def my_max(numbers):
maximum = numbers[0]
for num in numbers[1:]:
if num > maximum:
maximum = num
return maximum

# 快
maximum = max(numbers)

七、局部变量优化

# 全局变量访问较慢
import math

def calculate_slow():
result = 0
for i in range(100000):
result += math.sqrt(i)
return result

# 局部变量访问更快
def calculate_fast():
result = 0
sqrt = math.sqrt # 缓存为局部变量
for i in range(100000):
result += sqrt(i)
return result

八、使用生成器节省内存

# 占用大量内存
def read_large_file(filename):
with open(filename) as f:
return f.readlines()

# 内存高效
def read_large_file_gen(filename):
with open(filename) as f:
for line in f:
yield line.strip()

九、使用NumPy加速数值计算

import numpy as np

# 纯Python(慢)
def python_sum():
data = list(range(1000000))
return sum([x**2 for x in data])

# NumPy(快)
def numpy_sum():
data = np.arange(1000000)
return np.sum(data**2)

十、并行处理

10.1 使用多进程处理CPU密集型任务

from multiprocessing import Pool

def cpu_intensive_task(n):
return sum(i**2 for i in range(n))

# 串行
results = [cpu_intensive_task(1000000) for _ in range(4)]

# 并行
with Pool(4) as pool:
results = pool.map(cpu_intensive_task, [1000000] * 4)

10.2 使用多线程处理I/O密集型任务

from concurrent.futures import ThreadPoolExecutor
import requests

def fetch_url(url):
return requests.get(url).text

urls = ['https://example.com'] * 10

# 串行
results = [fetch_url(url) for url in urls]

# 并行
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(fetch_url, urls))

十一、使用__slots__减少内存占用

# 普通类
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

# 使用__slots__
class PointSlots:
__slots__ = ['x', 'y']

def __init__(self, x, y):
self.x = x
self.y = y

# PointSlots实例占用更少内存

十二、避免不必要的对象创建

# 低效
def process_items(items):
for item in items:
temp_list = [] # 每次循环都创建新列表
temp_list.append(item)
process(temp_list)

# 高效
def process_items(items):
temp_list = [] # 只创建一次
for item in items:
temp_list.clear()
temp_list.append(item)
process(temp_list)

十三、使用适当的算法

# O(n²) 冒泡排序
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]

# O(n log n) 内置排序
arr.sort() # 或 sorted(arr)

十四、延迟导入

# 在模块顶部导入所有内容可能很慢
import heavy_module

def rarely_used_function():
# 只在需要时导入
import heavy_module
return heavy_module.do_something()

十五、使用Cython加速

# 安装: pip install cython
# 创建 .pyx 文件

# example.pyx
def fibonacci(int n):
cdef int a = 0, b = 1, i
for i in range(n):
a, b = b, a + b
return a

# 编译后速度显著提升

十六、数据库查询优化

# 低效:N+1查询问题
users = User.query.all()
for user in users:
print(user.profile.bio) # 每次都查询数据库

# 高效:使用join预加载
users = User.query.join(Profile).all()
for user in users:
print(user.profile.bio) # 不需要额外查询

十七、性能优化的黄金法则

1. 先测量,再优化(不要过早优化)
2. 优化瓶颈,而不是整个代码
3. 选择合适的数据结构和算法
4. 使用内置函数和标准库
5. 考虑使用C扩展或Cython
6. 权衡时间复杂度和空间复杂度
7. 编写可读的代码,然后优化关键部分

十八、总结

Python性能优化是一个系统工程,需要从算法、数据结构、语言特性等多个角度考虑。关键是先通过性能分析工具找出瓶颈,然后针对性地优化。记住,可读性和可维护性同样重要,不要为了微小的性能提升而牺牲代码质量。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询