本文目录导读:

- 初始版本:最直接的实现
- 第一次优化:使用更高效的字典方法
- 第二次优化:使用defaultdict
- 第三次优化:使用Counter类
- 第四次优化:处理更复杂的文本(大小写和标点)
- 第五次优化:性能优化(使用生成器)
- 第六次优化:处理大文件(流式处理)
- 第七次优化:并行处理
- 性能对比测试
- 优化建议
我来通过一个具体的案例,逐步演示Python代码的优化过程,我们用一个统计文本中单词频率的例子。
初始版本:最直接的实现
def count_words(text):
"""
统计文本中每个单词出现的次数
"""
word_count = {}
# 分割文本为单词
words = text.split()
# 统计每个单词出现次数
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
return word_count
# 测试
text = "hello world hello python world python hello"
result = count_words(text)
print(result) # {'hello': 3, 'world': 2, 'python': 2}
第一次优化:使用更高效的字典方法
def count_words_v1(text):
"""
优化1:使用get()方法简化代码
"""
word_count = {}
for word in text.split():
word_count[word] = word_count.get(word, 0) + 1
return result
第二次优化:使用defaultdict
from collections import defaultdict
def count_words_v2(text):
"""
优化2:使用defaultdict避免键检查
"""
word_count = defaultdict(int)
for word in text.split():
word_count[word] += 1
return dict(word_count)
第三次优化:使用Counter类
from collections import Counter
def count_words_v3(text):
"""
优化3:使用Counter,一行搞定
"""
return Counter(text.split())
第四次优化:处理更复杂的文本(大小写和标点)
import re
from collections import Counter
def count_words_v4(text):
"""
优化4:处理标点符号和大小写
"""
# 移除标点符号并转为小写
cleaned_text = re.sub(r'[^\w\s]', '', text.lower())
return Counter(cleaned_text.split())
第五次优化:性能优化(使用生成器)
import re
from collections import Counter
def count_words_v5(text):
"""
优化5:使用生成器表达式节省内存
"""
# 生成器表达式,一次只处理一个单词
words = (word.lower().strip('.,!?;:') for word in re.findall(r'\b\w+\b', text))
return Counter(words)
第六次优化:处理大文件(流式处理)
import re
from collections import Counter
import mmap
def count_words_streaming(filename):
"""
优化6:处理大文件,避免一次加载到内存
"""
word_counts = Counter()
# 使用mmap高效读取大文件
with open(filename, 'r+b') as f:
# 内存映射文件
with mmap.mmap(f.fileno(), 0) as mmapped_file:
# 逐块读取
chunk_size = 8192
partial_word = ""
for chunk in iter(lambda: mmapped_file.read(chunk_size), b''):
text = partial_word + chunk.decode('utf-8')
# 确保最后一个单词完整
if not text.endswith(' '):
last_space = text.rfind(' ')
if last_space != -1:
partial_word = text[last_space+1:]
text = text[:last_space]
else:
partial_word = text
continue
else:
partial_word = ""
words = re.findall(r'\b\w+\b', text.lower())
word_counts.update(words)
return dict(word_counts)
第七次优化:并行处理
from collections import Counter
import re
from multiprocessing import Pool
import os
def process_chunk(chunk):
"""处理文本块"""
words = re.findall(r'\b\w+\b', chunk.lower())
return Counter(words)
def count_words_parallel(filename, num_processes=4):
"""
优化7:使用多进程并行处理
"""
# 获取文件大小
file_size = os.path.getsize(filename)
chunk_size = file_size // num_processes
chunks = []
with open(filename, 'r', encoding='utf-8') as f:
# 分割文件
for i in range(num_processes):
start = i * chunk_size
f.seek(start)
if i > 0:
# 跳到完整单词开始
f.readline()
if i < num_processes - 1:
data = f.read(chunk_size)
# 确保在单词边界结束
last_space = data.rfind(' ')
if last_space != -1:
data = data[:last_space]
chunks.append(data)
else:
chunks.append(f.read())
# 并行处理
with Pool(num_processes) as pool:
counters = pool.map(process_chunk, chunks)
# 合并结果
final_counter = Counter()
for c in counters:
final_counter.update(c)
return dict(final_counter)
性能对比测试
import time
def performance_test():
"""性能测试函数"""
# 生成测试数据
test_text = " ".join(["hello world python" for _ in range(100000)])
functions = [
("基本版本", count_words),
("get优化", count_words_v1),
("defaultdict", count_words_v2),
("Counter", count_words_v3),
("处理标点", count_words_v4),
("生成器优化", count_words_v5),
]
for name, func in functions:
start_time = time.time()
for _ in range(100):
func(test_text)
end_time = time.time()
print(f"{name}: {end_time - start_time:.4f}秒")
| 版本 | 改进点 | 适用场景 |
|---|---|---|
| v0 | 基础实现 | 小数据量,代码可读性优先 |
| v1 | 使用get() | 微优化,减少代码行数 |
| v2 | 使用defaultdict | 需要频繁插入字典 |
| v3 | 使用Counter | 通用计数场景 |
| v4 | 文本清洗 | 真实文本处理 |
| v5 | 生成器优化 | 内存受限场景 |
| v6 | 流式处理 | 大文件处理 |
| v7 | 并行处理 | 多核CPU,超大文件 |
优化建议
- 先功能,后优化:确保代码正确性
- 使用合适的工具:如Counter替代手动计数
- 考虑数据规模:不同规模有不同的优化策略
- 使用内置函数:Python内置函数通常比循环快
- 减少属性访问:将频繁访问的方法赋值给局部变量
- 使用profiler:先找出瓶颈再优化
# 使用cProfile进行性能分析示例
import cProfile
def profile_example():
text = "hello world " * 100000
cProfile.run('count_words_v3(text)')
通过这个案例,你可以看到如何从简单的实现逐步优化到高性能的版本,优化的关键在于理解业务场景和数据规模,选择最合适的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播