当前位置: 代码网 > it编程>前端脚本>Python > 5个Python性能优化技巧分享(代码速度提升100倍)

5个Python性能优化技巧分享(代码速度提升100倍)

2026年09月01日 Python 我要评论
你一定有过这种感觉:代码逻辑写对了,结果也对,但跑起来就是慢。一个循环要跑几分钟,一个数据处理脚本要等半小时,你盯着屏幕发呆,怀疑是不是电脑该换了。其实大概率不是电脑的问题,而是你的代码"姿

你一定有过这种感觉:

代码逻辑写对了,结果也对,但跑起来就是慢。一个循环要跑几分钟,一个数据处理脚本要等半小时,你盯着屏幕发呆,怀疑是不是电脑该换了。

其实大概率不是电脑的问题,而是你的代码"姿势"不对。python本身确实不是最快的语言,但大多数人的python代码连它应有速度的1%都没发挥出来。

下面这5个优化技巧,每一个都能带来数量级的性能提升。它们不是什么高深理论,而是实打实能让你今天就用上的方法。

技巧一:把for循环换成向量化(提升10-100倍)

这是最大的一颗低垂果实。绝大多数python慢代码,罪魁祸首都是for循环。

慢代码长这样

# 计算100万个数的平方
import time

nums = list(range(1_000_000))

start = time.time()
result = []
for n in nums:
    result.append(n ** 2)
end = time.time()

print(f"耗时:{end - start:.4f} 秒")  # 约 0.15 秒

看着还行?那是因为数据量还不够大。当数据量到1000万时,这个循环要跑将近2秒。而且这只是最简单的计算,如果循环里涉及条件判断、字典查找、字符串操作,速度会进一步恶化。

优化后

import numpy as np
import time

nums = np.arange(1_000_000)

start = time.time()
result = nums ** 2  # 向量化运算,一行搞定
end = time.time()

print(f"耗时:{end - start:.6f} 秒")  # 约 0.002 秒

75倍的差距。 ​ 而且代码还更短更清晰了。

为什么差距这么大?

python的for循环,每一次迭代都要做类型检查、函数调用、内存分配。而numpy的向量化运算,底层是c语言写的,直接在连续内存块上做批量计算,跳过了python的所有解释器开销。

实战场景:数据处理

假设你有一个10万行的销售数据,要计算每条记录的"折扣后价格":

# ❌ 慢:for循环逐行计算
df['final_price'] = none
for i in range(len(df)):
    df.loc[i, 'final_price'] = df.loc[i, 'price'] * (1 - df.loc[i, 'discount'])
# 10万行,约 20-30 秒

# ✅ 快:向量化
df['final_price'] = df['price'] * (1 - df['discount'])
# 10万行,约 0.01 秒

2000倍以上的差距。 ​ 这就是很多人觉得pandas"快得离谱"的原因——它底层全是向量化运算。

适用场景

操作类型用for循环用向量化
数值计算✅ numpy
dataframe列运算✅ pandas直接运算
字符串处理✅ pandas.str 或 regex
条件筛选✅ 布尔索引
逐行依赖前一行结果✅ 有时不得不用❌ 试试 cumsum/shift

核心原则:只要你的操作能写成"对整个数组/列做同一个运算",就不要用for循环。

技巧二:用生成器替代列表(内存降90%,速度提升2-5倍)

当你处理大文件或大数据集时,内存往往是瓶颈。内存不够,系统开始用磁盘交换(swap),速度瞬间掉到地板上。

慢代码

# 读取一个大文件,把所有行加载到内存
def read_lines(filename):
    lines = []
    with open(filename, 'r') as f:
        for line in f:
            lines.append(line.strip())
    return lines

# 如果文件有100万行,lines列表占用几百mb内存

优化后

# 用生成器,一次只加载一行到内存
def read_lines(filename):
    with open(filename, 'r') as f:
        for line in f:
            yield line.strip()

# 使用
for line in read_lines('huge_file.txt'):
    process(line)  # 逐行处理,内存占用恒定在几kb

更pythonic的写法

# 直接用生成器表达式
squares = (x ** 2 for x in range(10_000_000))  # 几乎不占内存
# 对比列表推导式
squares = [x ** 2 for x in range(10_000_000)]  # 立即占用几百mb

实战场景:处理大日志文件

# ❌ 慢:一次性读入内存
with open('server.log', 'r') as f:
    lines = f.readlines()  # 2gb日志文件?内存直接爆
errors = [line for line in lines if 'error' in line]

# ✅ 快:流式处理
errors = []
with open('server.log', 'r') as f:
    for line in f:  # 一次只读一行
        if 'error' in line:
            errors.append(line)

如果只需要统计错误数量,甚至不需要存下来:

error_count = sum(1 for line in open('server.log') if 'error' in line)

内存占用从gb级别降到kb级别,速度自然也快了。

技巧三:用集合和字典替代列表查找(提升100-1000倍)

在列表里查找元素,python要做线性扫描——从头到尾一个一个比对。列表有100万个元素,最坏情况要比较100万次。

慢代码

# 检查10万个id是否在白名单中
whitelist = list(range(1_000_000))  # 100万个id的列表
user_ids = list(range(0, 2_000_000, 20))  # 10万个待检查的id

start = time.time()
valid_users = []
for uid in user_ids:
    if uid in whitelist:  # 每次都是o(n)的线性查找
        valid_users.append(uid)
end = time.time()

print(f"耗时:{end - start:.2f} 秒")  # 约 50-80 秒

优化后

# 把白名单转成集合
whitelist_set = set(whitelist)

start = time.time()
valid_users = [uid for uid in user_ids if uid in whitelist_set]  # o(1)查找
end = time.time()

print(f"耗时:{end - start:.4f} 秒")  # 约 0.02 秒

3000倍以上的差距。

为什么集合这么快?

列表查找是线性扫描(o(n)),集合和字典的查找基于哈希表(o(1))。原理类似字典查字:列表是从头翻到尾,集合是直接跳到那一页。

实战场景:数据去重和关联

# ❌ 慢:用列表做去重
unique_items = []
for item in huge_list:
    if item not in unique_items:  # o(n)查找
        unique_items.append(item)

# ✅ 快:用集合做去重
unique_items = list(set(huge_list))  # o(1)查找,一行搞定

技巧四:用内置函数和库函数(提升5-50倍)

python的内置函数和标注库,底层都是c语言实现的。你自己写的python代码再怎么优化,也跑不过c。

慢代码

# 自己写求和
total = 0
for num in numbers:
    total += num

# 自己写排序
def bubble_sort(arr):
    for i in range(len(arr)):
        for j in range(len(arr)-1-i):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]

优化后

# 用内置函数
total = sum(numbers)        # c语言实现,快5-10倍
sorted_arr = sorted(arr)    # timsort算法,快20-50倍
max_val = max(numbers)      # 内置,快很多

实战场景:字符串拼接

# ❌ 慢:字符串累加
result = ''
for word in words:
    result += word + ' '  # 每次都创建新字符串对象

# ✅ 快:join方法
result = ' '.join(words)  # 一次分配内存,快10-100倍

实战场景:计数

# ❌ 慢:手动计数
counts = {}
for item in items:
    if item in counts:
        counts[item] += 1
    else:
        counts[item] = 1

# ✅ 快:用counter
from collections import counter
counts = counter(items)  # 快3-5倍,代码还短

常用高性能内置替代方案

你的代码用这个替代提速倍数
手动for循环求和sum()5-10x
手动排序sorted()20-50x
字符串拼接 +='sep'.join()10-100x
手动计数counter3-5x
手动查找最大/最小max()/min()5-10x
手动反转列表reversed()10-20x
手动判断是否存在any()/all()5-10x

技巧五:用多进程突破gil限制(提升4-8倍)

python有个著名的"缺陷"叫gil(全局解释器锁),它让同一时刻只有一个线程能执行python字节码。所以多线程对cpu密集型任务几乎没用。

多进程可以绕过gil,每个进程有独立的python解释器和内存空间,可以真正利用多核cpu。

慢代码

import time

def heavy_task(n):
    """模拟一个耗时计算"""
    result = 0
    for i in range(n):
        result += i ** 0.5
    return result

tasks = [10_000_000] * 8  # 8个耗时任务

start = time.time()
results = []
for task in tasks:
    results.append(heavy_task(task))
end = time.time()

print(f"单进程耗时:{end - start:.2f} 秒")  # 约 16-20 秒

优化后

import time
from multiprocessing import pool

start = time.time()
with pool(processes=8) as pool:  # 8个进程,对应8个cpu核心
    results = pool.map(heavy_task, tasks)
end = time.time()

print(f"多进程耗时:{end - start:.2f} 秒")  # 约 3-5 秒

4-6倍的提升。 ​ 如果你有8核cpu,理论上限就是8倍(实际因为进程创建和通信开销,到不了8倍,但4-6倍是很常见的)。

实战场景:批量图片处理

from multiprocessing import pool
from pil import image
import os

def resize_image(filename):
    """调整单张图片尺寸"""
    img_path = f"inputs/{filename}"
    img = image.open(img_path)
    img = img.resize((224, 224))
    img.save(f"outputs/{filename}")
    return filename

image_files = os.listdir("inputs")

# 用多进程并行处理
with pool(processes=os.cpu_count()) as pool:
    pool.map(resize_image, image_files)

注意事项

多进程不是银弹,有几个坑要注意:

  1. 进程启动有开销:任务太小(比如只算几毫秒),多进程的创建开销反而比直接跑还大。一般任务耗时在0.1秒以上才值得用多进程。
  2. 内存占用翻倍:每个进程都有独立的内存空间。如果主进程占2gb内存,开8个进程可能占到16gb+。确保内存够用。
  3. windows上注意 __main__ 保护:windows的进程创建方式不同,必须把主代码放在 if __name__ == '__main__': 下面,否则会无限递归创建进程。
# windows上正确的写法
def main():
    # 你的多进程代码
    pass

if __name__ == '__main__':
    main()

综合实战:优化一个真实场景

把5个技巧结合起来,看一个真实的优化案例。

场景:分析1000万条用户行为日志

需求:从1000万条日志中,找出每个用户最后10次行为中,有多少次是"购买"行为,并且只统计购买次数≥3的用户。

原始代码(慢)

# 读取日志
logs = []
with open('user_logs.txt', 'r') as f:
    for line in f:
        user_id, action, timestamp = line.strip().split(',')
        logs.append((int(user_id), action, int(timestamp)))

# 按用户分组
user_logs = {}
for user_id, action, timestamp in logs:
    if user_id not in user_logs:
        user_logs[user_id] = []
    user_logs[user_id].append((action, timestamp))

# 分析每个用户
result = {}
for user_id, actions in user_logs.items():
    # 按时间排序
    actions.sort(key=lambda x: x[1])
    # 取最后10次
    last_10 = actions[-10:]
    # 统计购买次数
    purchase_count = 0
    for action, _ in last_10:
        if action == 'purchase':
            purchase_count += 1
    if purchase_count >= 3:
        result[user_id] = purchase_count

print(len(result))

运行时间:约 120-180 秒。

优化后代码

import pandas as pd
from collections import defaultdict

# 技巧二:用pandas高效读取(底层c实现)
df = pd.read_csv('user_logs.txt', names=['user_id', 'action', 'timestamp'])

# 技巧一:向量化过滤
purchases = df[df['action'] == 'purchase']

# 技巧三:用groupby(底层用哈希表,比手动字典快)
user_purchase_counts = (
    purchases.groupby('user_id')
    .size()
    .reset_index(name='purchase_count')
)

# 过滤购买次数≥3的用户
result = user_purchase_counts[user_purchase_counts['purchase_count'] >= 3]

print(len(result))

运行时间:约 3-5 秒。

提速30-50倍。 ​ 而且代码从30行变成了10行,可读性反而更好了。

如果数据量更大(上亿行),还可以进一步:

# 技巧四+五:分块读取 + 多进程
chunk_size = 1_000_000
results = []

for chunk in pd.read_csv('user_logs.txt', names=['user_id', 'action', 'timestamp'], chunksize=chunk_size):
    purchases = chunk[chunk['action'] == 'purchase']
    counts = purchases.groupby('user_id').size()
    results.append(counts)

# 合并结果
final_counts = pd.concat(results).groupby(level=0).sum()
result = final_counts[final_counts >= 3]

性能优化速查表

把5个技巧总结成一张速查表,方便你写代码时对照:

技巧核心思想适用场景预期提速
向量化用numpy/pandas替代for循环数值计算、数据处理10-100x
生成器用yield或()替代[]大文件读取、大数据流内存降90%+
集合/字典用set/dict替代list查找成员判断、去重、关联100-1000x
内置函数用c实现的内置函数求和、排序、计数等5-50x
多进程绕过gil用多核cpucpu密集型批量任务4-8x

总结

优化python代码,最重要的不是记住这些技巧,而是养成一个习惯:写完代码后,问自己一句"这里有没有更pythonic的写法?"

大多数情况下:

  • 你在写for循环 → 想想能不能向量化
  • 你在列表里做查找 → 想想能不能用集合
  • 你在手动实现常见功能 → 想想有没有内置函数
  • 你在处理大数据 → 想想能不能用生成器
  • 你在跑cpu密集型任务 → 想想能不能用多进程

不需要一开始就追求极致性能。先让代码跑起来,再找到瓶颈,针对性优化。用 time 模块或 cprofile 测一下,哪里慢优化哪里,比盲目优化有效得多。

# 快速定位瓶颈
import cprofile
cprofile.run('your_function()')

这行代码会告诉你每个函数花了多少时间,哪里是真正的瓶颈一目了然。

以上就是5个python性能优化技巧分享(代码速度提升100倍)的详细内容,更多关于python性能优化的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com