Python 性能优化:从入门到精通的实用指南

Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!

python系列文章目录

01-Python 基础语法入门:从变量到输入输出,零基础也能学会!
02-Python 流程控制终极指南:if-else 和 for-while深度解析
03-Python 列表与元组全攻略:从新手到高手的必备指南
04-Python 字典与集合:从入门到精通的全面解析
05-Python函数入门指南:从定义到应用
06-Python 函数高级特性:从默认参数到闭包的全面解析
07-Python 模块与包:从零到自定义的全面指南
08-Python异常处理:从入门到精通的实用指南
09-Python 文件操作:从零基础到日志记录实战
10-Python面向对象编程入门:从类与对象到方法与属性
11-Python类的方法与属性:从入门到进阶的全面解析
12-Python继承与多态:提升代码复用与灵活性的关键技术
13-掌握Python魔法方法:如何用__add__和__len__自定义类的行为
14-python面向对象编程总结:从基础到进阶的 OOP 核心思想与设计技巧
15-掌握 Python 高级特性:深入理解迭代器与生成器
16-用 Python 装饰器提升效率:日志与权限验证案例
17-再也不怕资源泄漏!Python 上下文管理器,with语句全攻略
18-Python 标准库必备模块:math、random、os、json 全解析

19-Python 性能优化:从入门到精通的实用指南


文章目录

  • Langchain系列文章目录
  • python系列文章目录
  • 前言
  • [一、影响 Python 性能的因素](#一、影响 Python 性能的因素)
    • [1.1 时间复杂度](#1.1 时间复杂度)
      • [1.1.1 为什么时间复杂度重要?](#1.1.1 为什么时间复杂度重要?)
      • [1.1.2 怎么优化时间复杂度?](#1.1.2 怎么优化时间复杂度?)
    • [1.2 空间复杂度](#1.2 空间复杂度)
      • [1.2.1 空间复杂度为啥关键?](#1.2.1 空间复杂度为啥关键?)
      • [1.2.2 怎么优化空间复杂度?](#1.2.2 怎么优化空间复杂度?)
  • [二、Python 性能优化技巧](#二、Python 性能优化技巧)
    • [2.1 避免重复计算](#2.1 避免重复计算)
      • [2.1.1 使用缓存机制](#2.1.1 使用缓存机制)
      • [2.1.2 预计算和惰性计算](#2.1.2 预计算和惰性计算)
    • [2.2 减少 IO 操作](#2.2 减少 IO 操作)
      • [2.2.1 批量处理数据](#2.2.1 批量处理数据)
      • [2.2.2 使用异步 IO](#2.2.2 使用异步 IO)
  • [三、使用 `timeit` 模块测量代码性能](#三、使用 timeit 模块测量代码性能)
    • [3.1 `timeit` 模块简介](#3.1 timeit 模块简介)
      • [3.1.1 为什么用 `timeit`?](#3.1.1 为什么用 timeit?)
    • [3.2 如何使用 `timeit` 测量代码性能](#3.2 如何使用 timeit 测量代码性能)
      • [3.2.1 命令行使用 `timeit`](#3.2.1 命令行使用 timeit)
      • [3.2.2 在代码中使用 `timeit`](#3.2.2 在代码中使用 timeit)
  • 四、总结

前言

Hey,你有没有遇到过这样的情况:代码跑得太慢,CPU 风扇狂转,甚至内存直接爆满?在 Python 开发中,性能问题是个绕不过去的坎儿。无论是处理大数据、写爬虫,还是开发 Web 应用,优化性能都能让你的程序更快、更省资源。这篇文章的目标很简单:带你从零开始,搞懂影响 Python 性能的因素,学会几个超实用的优化技巧,还要教你怎么用 timeit 模块测测代码到底有多快。不管你是刚入门的小白,还是有点经验的开发者,这里都有干货等着你!

本文会聊三大块:

  • 影响 Python 性能的"幕后黑手":时间复杂度和空间复杂度。
  • 优化代码的"锦囊妙计":避免重复计算、减少 IO 操作。
  • 性能检测的"秘密武器":timeit 模块。

准备好了吗?咱们这就开始!


一、影响 Python 性能的因素

性能优化得先知道问题出在哪儿,对吧?Python 虽然简单好用,但有些地方不注意就会拖慢速度。这部分咱们聊聊两个核心因素:时间复杂度和空间复杂度。

1.1 时间复杂度

时间复杂度听起来有点学术,其实就是"你的代码跑起来需要多久"。它跟数据量大小直接挂钩,数据越多,影响越明显。

1.1.1 为什么时间复杂度重要?

简单说,时间复杂度决定了一个算法的效率。比如你在列表里找个数,数据量小还好,可要是列表里有几百万条数据,效率低的算法能让你等到怀疑人生。

  • 举个例子 :用列表和集合找数字的区别。

    python 复制代码
    # 列表找数字,时间复杂度 O(n)
    my_list = [1, 2, 3, 4, 5]
    if 3 in my_list:  # 得一个个检查
        print("找到啦!")
    
    # 集合找数字,时间复杂度 O(1)
    my_set = {1, 2, 3, 4, 5}
    if 3 in my_set:  # 直接定位,超快
        print("找到啦!")
  • 关键点:列表是线性查找,时间复杂度是 O(n);集合用哈希表,平均时间复杂度是 O(1)。数据量越大,差距越明显。

1.1.2 怎么优化时间复杂度?

  • 建议 :需要频繁查找时,用集合(set)或字典(dict)代替列表。
  • 场景:比如去重、查重这种操作,集合简直是神器。

1.2 空间复杂度

时间跑得快还不够,内存用得少也很重要。空间复杂度就是"你的代码占了多少内存"。

1.2.1 空间复杂度为啥关键?

Python 自动管理内存,但用错了数据结构,内存照样吃紧。比如存一堆数字,用列表和生成器差别可不小。

  • 举个例子

    python 复制代码
    # 列表存一百万个数,全都加载到内存
    my_list = [i for i in range(1000000)]  # 内存占用大
    
    # 生成器,边用边生成,内存几乎不占
    my_gen = (i for i in range(1000000))  # 超省空间
  • 关键点:列表把所有数据都存下来,空间复杂度 O(n);生成器只存当前值,空间复杂度接近 O(1)。

1.2.2 怎么优化空间复杂度?

  • 建议:大数据场景下,优先用生成器或迭代器。
  • 场景:比如读取大文件、处理流数据,用生成器能省下不少内存。

二、Python 性能优化技巧

知道了影响性能的因素,咱们得动手优化代码。这部分分享两个超实用的技巧:避免重复计算和减少 IO 操作。

2.1 避免重复计算

重复计算就像你炒菜时把同一个葱花切了十遍,太浪费时间!Python 里有些操作可以提前做好,省下不少力气。

2.1.1 使用缓存机制

缓存就是把算过的结果存起来,下次直接拿来用。Python 自带一个神器:functools.lru_cache

  • 代码示例 :优化递归计算斐波那契数列。

    python 复制代码
    from functools import lru_cache
    
    @lru_cache(maxsize=128)  # 缓存最多 128 个结果
    def fibonacci(n):
        if n < 2:
            return n
        return fibonacci(n-1) + fibonacci(n-2)
    
    print(fibonacci(50))  # 超快!
  • 关键点:没缓存时,递归会重复算好多次;加了缓存,直接查表,时间从"天文数字"变成"秒级"。

  • 场景:递归函数、频繁调用的计算任务。

2.1.2 预计算和惰性计算

  • 预计算:提前把结果算好,比如程序启动时把常用数据准备好。

  • 惰性计算 :用到时再算,用生成器就是典型例子。

    python 复制代码
    def lazy_range(n):
        i = 0
        while i < n:
            yield i  # 每次只生成一个数
            i += 1
    
    for num in lazy_range(1000):  # 按需取值
        print(num)
  • 建议:不常用的数据用惰性计算,常用的小数据用预计算。

2.2 减少 IO 操作

IO 操作(比如读文件、发网络请求)特别慢,减少它的次数能让代码飞起来。

2.2.1 批量处理数据

别一行行读文件,一次性读完再处理效率更高。

  • 代码示例

    python 复制代码
    # 逐行读,IO 次数多
    def process(line):
        print(line)
    
    with open('file.txt', 'r') as f:
        for line in f:  # 每次都调用 IO
            process(line)
    
    # 一次性读,IO 次数少
    with open('file.txt', 'r') as f:
        content = f.read()  # 一次读完
        lines = content.splitlines()
        for line in lines:
            process(line)
  • 关键点:批量操作把多次 IO 变成一次,速度提升明显。

  • 场景:读写大文件、数据库操作。

2.2.2 使用异步 IO

网络请求多的时候,等一个完再发下一个太慢,用异步 IO 可以同时处理。

  • 代码示例 :用 asyncio 抓网页。

    python 复制代码
    import asyncio
    import aiohttp
    
    async def fetch_url(url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                return await response.text()
    
    async def main():
        urls = ['http://example.com', 'http://example.org']
        tasks = [fetch_url(url) for url in urls]
        results = await asyncio.gather(*tasks)
        print(results[0][:100])  # 只打印前 100 个字符
    
    asyncio.run(main())
  • 关键点:异步 IO 让多个请求并行,特别适合爬虫或高并发任务。

  • 场景:网络密集型任务。


三、使用 timeit 模块测量代码性能

优化完代码,怎么知道效果咋样?用 timeit 模块测一测就知道了!

3.1 timeit 模块简介

timeit 是 Python 自带的小工具,专门测小段代码的运行时间。它会重复跑代码取平均值,结果很靠谱。

3.1.1 为什么用 timeit

手动用 time.time() 测时间不准,因为系统负载会干扰。timeit 跑很多次,数据更稳定。

3.2 如何使用 timeit 测量代码性能

3.2.1 命令行使用 timeit

直接在终端跑,适合快速测试。

  • 示例 :测列表推导式的速度。

    bash 复制代码
    python -m timeit "sum([i for i in range(1000)])"
  • 输出:类似"1000 loops, best of 5: 123 usec per loop",表示平均每次多久。

  • 建议:调试小代码时用这个,简单又快。

3.2.2 在代码中使用 timeit

想在脚本里测?也很简单。

  • 代码示例

    python 复制代码
    import timeit
    
    def my_function():
        return sum([i for i in range(1000)])
    
    # 跑 100 次,测总时间
    execution_time = timeit.timeit(my_function, number=100)
    print(f"总耗时: {execution_time} 秒")
  • 关键点number 是运行次数,自己调,别设太大跑不动。

  • 场景:对比不同实现方案的性能。


四、总结

本文聊了 Python 性能优化的三大块:

  • 影响因素:时间复杂度管速度,空间复杂度管内存,选对数据结构很关键。
  • 优化技巧:避免重复计算用缓存和生成器,减少 IO 用批量和异步。
  • 测量工具timeit 帮你量化优化效果。

希望你看完能有所收获,赶紧把这些技巧用到自己的代码里吧!有什么问题,随时问我哦~


相关推荐
孙桂月17 分钟前
Python爬取数据(二)
开发语言·python
白白糖19 分钟前
组合与括号生成(回溯)
python·算法·力扣
chxin1401635 分钟前
PyTorch 学习笔记
pytorch·笔记·python
好奇的菜鸟43 分钟前
Scoop + Kotlin 极简开发环境搭建指南
android·开发语言·kotlin
滴答滴答嗒嗒滴44 分钟前
Python 小练习系列 | Vol.14:掌握偏函数 partial,用函数更丝滑!
开发语言·python
leluckys1 小时前
swift-oc和swift block和代理
开发语言·ios·swift
魂兮-龙游1 小时前
C语言:字符串处理函数strstr分析
c语言·开发语言·数据处理·字符串处理
oioihoii1 小时前
AI随身翻译设备:从翻译工具到智能生活伴侣
人工智能·生活
努力当一个优秀的程序员1 小时前
0.机器学习基础
人工智能·机器学习
来自星星的坤1 小时前
Spring Boot 邮件发送配置遇到的坑:解决 JavaMailSenderImpl 未找到的错误
java·开发语言·spring boot·后端·spring