本文目录导读:

我来详细说明Python脚本优化进程内存占用的一些关键策略和技巧:
数据类型优化
使用更紧凑的数据结构
# 避免使用Python对象列表(内存开销大)
# 不推荐
points = [(1.0, 2.0), (3.0, 4.0)] # 每个元组约56字节
# 推荐方案
## 使用numpy数组
import numpy as np
points = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32) # 每个点仅8字节
## 使用array模块
from array import array
numbers = array('d', [1.0, 2.0, 3.0, 4.0]) # 紧凑的C类型数组
使用slots减少对象开销
# 不推荐
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# 推荐
class Point:
__slots__ = ['x', 'y'] # 减少约50%的内存
def __init__(self, x, y):
self.x = x
self.y = y
生成器与惰性计算
# 不推荐 - 立即创建完整列表
def load_data():
return [process(item) for item in range(1000000)]
# 推荐 - 使用生成器
def load_data():
for item in range(1000000):
yield process(item)
# 或者使用迭代器
def process_large_file():
with open('large_file.txt', 'r') as f:
for line in f: # 逐行处理,而不是一次性读取所有行
yield process_line(line.strip())
减少复制与临时对象
# 不推荐 - 创建大量临时对象
def process_data(data):
result = []
for item in data:
result.append(item * 2)
return result
# 推荐 - 原地修改
def process_data(data):
for i in range(len(data)):
data[i] *= 2 # 原地修改,避免创建新列表
return data
# 使用view而不是copy
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
view = arr[1:3] # 创建视图,不是副本
view[0] = 100 # 修改会反映在原数组
字符串优化
# 不推荐
text = ""
for item in items:
text += str(item) # 每次创建新字符串
# 推荐
parts = [str(item) for item in items]
text = ''.join(parts) # 一次性创建,更高效
# 使用f-string(Python 3.6+)
# 内存效率更高
name = "World"
greeting = f"Hello {name}" # 推荐使用
使用弱引用
import weakref
class Cache:
def __init__(self):
self._cache = {}
def get_or_create(self, key, creator_func):
if key not in self._cache:
self._cache[key] = weakref.ref(creator_func())
return self._cache[key]()
内存映射文件
import mmap
import os
def process_large_file(filepath):
with open(filepath, 'rb') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# 像操作字符串一样操作文件内容
current_pos = 0
while True:
line_end = mm.find(b'\n', current_pos)
if line_end == -1:
break
line = mm[current_pos:line_end]
process_line(line)
current_pos = line_end + 1
使用内置的优化工具
# 使用sys.getsizeof检查内存占用
import sys
obj = [1, 2, 3]
print(f"对象大小: {sys.getsizeof(obj)} bytes")
# 使用tracemalloc追踪内存分配
import tracemalloc
tracemalloc.start()
# 你的代码...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
循环优化
# 不推荐
for i in range(len(data)):
process(data[i])
# 推荐 - 直接迭代
for item in data:
process(item)
# 使用局部变量加速
def process_fast(data):
local_process = process # 避免全局查找
for item in data:
local_process(item)
监控与分析工具
# 使用memory_profiler
# pip install memory_profiler
from memory_profiler import profile
@profile
def my_function():
# 你的代码
large_list = [i for i in range(1000000)]
return sum(large_list)
# 使用objgraph查找内存泄漏
import objgraph
# 查看对象引用
objgraph.show_refs([my_object], filename='refs.png')
实践建议
-
先分析再优化:使用工具确定内存瓶颈
-
选择合适的数据结构:根据场景选择list, set, dict, deque等
-
及时释放资源:
with open('file.txt', 'r') as f: data = f.read() # 文件自动关闭,资源释放 -
使用上下文管理器:确保资源正确释放
-
考虑使用C扩展:对于性能关键部分,考虑使用Cython或编写C扩展
这些优化技术可以帮助显著减少内存使用,但要根据具体场景选择适当的优化策略,避免过度优化。