Py学习  »  Python

资深 Pythoner 所使用的10个高级代码技术

数据STUDIO • 2 天前 • 25 次点击  


代码性能优化对于创建高效、可扩展和反应灵敏的应用程序至关重要。作为一名资深 Python 开发人员,你在确保代码高效运行并满足性能要求方面发挥着至关重要的作用。

本文将深入探讨优化 Python 代码的高级技巧,包括有效使用数据结构和算法、基准测试、多线程等。准备好提升你的 Python 技能吧!如果有用,双击屏幕点个赞吧!

代码性能优化的重要性

出于以下几个原因,优化代码性能至关重要:

  • 增强用户体验: 更快的代码执行速度可以加快响应速度,提高资源使用效率,从而让最终用户满意。
  • 可扩展性: 经过优化的代码可以处理大量的工作负载,使应用程序能够随着需求的增加而从容扩展,并产生更高的收益。
  • 降低成本: 高效的代码能更好地利用计算资源,从而最大限度地降低基础设施和云服务的成本。

高级 Pythoner在性能优化中的作用

作为一名高级 Python 开发人员,你的职责是

  • 设计和编写符合性能要求的高效代码
  • 识别性能瓶颈并提出优化解决方案
  • 不断学习并掌握最新的性能最佳实践

高效使用数据结构和算法

代码优化的一个重要方面是了解数据结构和算法。正确的选择可以显著提高性能。

选择正确的数据结构

选择合适的数据结构会极大地影响代码的性能。例如,在执行查找时,set 或 dict要比在 list 中查找快得多。

# 使用列表进行成员测试
list_example = [12345]
if 5 in list_example:
    print("Found in list!")
# 使用集合进行更快速的成员测试
set_example = {12345}
if 5 in set_example:
    print("Found in set!")

考虑到时间复杂性、空间复杂性和内置操作等因素,始终为你的用例选择最合适的数据结构。

适当使用 Python 内置库

Python 的标准库是一个预建模块的宝库,可以帮助你编写高效的代码。例如, collectionsitertools 和 functools

from collections import defaultdict
from itertools import islice

# 使用 defaultdict 来简化复杂字典的创建
my_dict = defaultdict(list)
my_dict['key'].append('value')
# 使用 islice 对生成器进行更节省内存的切分
my_gen = (x**2 for x in range(10))
sliced_gen = islice(my_gen, 192)

Big-O 符号及其在算法选择中的重要性

Big-O 符号描述了算法在输入大小方面的性能。作为一名资深的 Python 开发人员,你应该能够自如地使用 Big-O 符号为你的任务选择合适的算法。

使用 Big-O 复杂度较低的算法可以大大提高性能。

例如,考虑一下这两个计算列表中元素出现次数的函数:

def count_elements_slow(input_list):
    output = {}
    for item in input_list:
        output[item] = input_list.count(item)
    return output

def count_elements_fast(input_list):
    output = {}
    for item in input_list:
        output[item] = output.get(item, 0) + 1
    return output

第一个函数  count_elements_slow 的时间复杂度为 O(n^2),而第二个函数 count_elements_fast 的时间复杂度为 O(n)。因此,对于大型输入列表,第二个函数的运行速度要快得多。

剖析和基准测试工具

发现性能瓶颈是优化代码的关键一步。使用剖析和基准测试工具可以帮助你确定需要改进的地方。

Python 内置的 cProfile 和 timeit 模块

Python 的标准库为剖析和基准测试提供了两个有用的工具:cProfile 和 timeit

cProfile 可以帮助你分析代码的运行时间,而 timeit 可以让你快速比较不同代码片段的运行速度。

import cProfile
import  timeit

def slow_function():
    pass
def fast_function():
    pass

# 使用 cProfile 剖析函数的执行
cProfile.run('slow_function()')
# 使用 timeit 比较 slow_function 与 fast_function 的执行速度setup_code = "from __main__ import slow_function, fast_function"
slow_time = timeit.timeit("slow_function()", setup=setup_code, number=10000)
fast_time = timeit.timeit("fast_function()", setup=setup_code, number=10000)
print(f"slow_function took {slow_time:.2f}s, fast_function took {fast_time:.2f}s")

Py-spy,Pyflame 和VizTracer等外部工具

还有一些外部工具可提供更高级的剖析和可视化功能,例如

  • Py-spy: 采样剖析器,可生成火焰图,用于可视化程序的执行情况
  • Pyflame: 另一种功能强大的剖析器,可生成火焰图
  • VizTracer: Python 的可视化工具,可生成时序图,帮助你识别瓶颈。

解释剖析结果并识别瓶颈

在分析剖析工具的结果时,必须将重点放在最耗时的操作上。一般来说,这些领域的优化将带来最显著的性能提升。

重新审视数据结构、算法和代码结构,找出可能的改进之处。

代码优化技术

编写高效代码是一门艺术,也是一门科学。通过一些简单的技巧和技术,你可以显著优化 Python 代码的性能。

循环优化和避免嵌套循环

循环优化是代码优化的一个重要方面。要加快 Python 中循环的速度,请考虑以下提示:

  • 尽可能使用内置函数,如 mapfilter 和 zip 代替循环
  • 尽量减少循环内的工作(例如,如果函数调用和计算不依赖于循环变量,则将它们移到循环之外)
  • 尽可能避免使用嵌套循环,因为它们会大大增加复杂性
# 简单循环优化示例
input_list = [12345]

# 展示循环
result_slow = []
for item in input_list:
    squared = item**2
    result_slow.append(squared)
# 使用列表推导式优化循环
result_fast = [item**2 for item in input_list]

利用列表推导式和生成器表达式

列表推导式和生成器表达式不仅更简洁,还能提高性能。请尽可能使用它们。

# 使用列表理解创建平方数列表
squared_list = [x ** 2 for x in  range(10)]

# 使用生成器表达式创建生成器,生成平方数
squared_gen = (x ** 2 for x in range(10))

利用 Python 的缓存机制

缓存昂贵函数调用的结果可以显著提高性能。Python 提供了 functools.lru_cache 装饰器来自动缓存函数调用的结果。

from functools import lru_cache

@lru_cache(maxsize=None)
def expensive_function(x):
    pass
# 该函数调用将被缓存,从而提高后续调用的性能
result = expensive_function(42)

多线程和多处理

利用 Python 的并发和并行能力可以大大提高性能,特别是对于 I/O 绑定和 CPU 绑定的任务。

了解全局解释器锁 (GIL)

全局解释器锁(GIL)是一种互斥机制,可以防止多个本地线程同时执行 Python 字节码。

虽然 GIL 提供了一些性能优势,但它也会限制线程实现的并行性。因此,在 Python 中使用多线程时,理解 GIL 至关重要。

使用 threading 和 multiprocessing 模块

Python 提供了 threading 和  multiprocessing 模块,分别用于处理线程和进程。threading适用于 I/O 绑定的任务,而 multiprocessing 则用于 CPU 绑定的任务,因为它可以有效地绕过 GIL。

import threading
import multiprocessing

def thread_function(arg1, arg2):
    pass
def process_function(arg1, arg2):
    pass
# 使用线程创建并启动新线程
t = threading.Thread(target=thread_function, args=(12))
t.start()
t.join()
# 使用多进程创建并启动一个新进程
p = multiprocessing.Process(target=process_function, args=(12))
p.start()
p.join()

使用 asyncio 实现并发编程

对于高度并发的 I/O 绑定任务,asyncio 是一个强大的模块,它允许你使用 Python 的 async 和 await 语法编写异步代码。




    
import asyncio

async def async_function():
    await asyncio.sleep(1)
    print("Hello from async_function!")
# 在 asyncio 事件循环中运行异步函数
loop = asyncio.get_event_loop()
loop.run_until_complete(async_function())
loop.close()

内存管理和垃圾回收

有效管理内存对优化性能至关重要。Python 的垃圾回收器会自动为不再使用的对象去分配内存,但了解它的工作原理有助于进一步提高内存使用率。

Python 的内存管理模型

Python 结合使用引用计数和垃圾回收来管理内存。当一个对象的引用计数为零时,它就会成为垃圾回收的候选对象。Python 中的循环垃圾收集器会检测并清理那些不可访问但引用计数仍不为零的循环对象。

微调垃圾收集器设置

你可以使用 gc 模块控制 Python 的垃圾回收器设置,以优化内存使用。

例如,你可以在代码的关键部分暂时禁用垃圾收集器以提高性能,或者根据应用程序的内存需求调整收集阈值。

import gc

# 暂时禁用垃圾回收器
gc.disable()
# 优化性能的关键代码段
# ...
# 重新启用垃圾回收器
gc.enable()

使用内存剖析工具(如 memory_profiler)

内存剖析工具(如 memory_profiler)可以帮助你检测和分析代码中的内存泄漏。

from


    
 memory_profiler import profile

@profile
def memory_leak_function():
    large_list = [x * 2 for x in range(0100000)]
    return large_list
result = memory_leak_function()

通过分析一段时间的内存使用情况,可以确定需要优化的地方,确保高效的内存管理。

输入/输出操作和文件处理

优化文件 I/O 操作可显著提高代码性能,尤其是在处理大文件时。

利用缓冲优化文件读写

缓冲可以通过减少系统调用次数来加快文件读写。Python 内置的 open 函数允许你指定缓冲模式和缓冲区大小。

# 使用自定义缓冲区大小读取文件
with open("large_file.txt""r", buffering=1024*1024as file:
    data = file.read()

# 用自定义缓冲区大小写入文件
with open("output_file.txt""w", buffering=1024*1024as file:
    file.write(data)

使用内存映射处理大文件

内存映射可以将文件映射到脚本的内存中,从而可以直接使用常规内存操作访问文件内容。Python 中的 mmap 模块提供了这种功能。

import mmap

with open( "large_file.txt""r"as file:
    # 对文件进行内存映射,以便快速访问
   mmapped_file = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
    # 像读取普通文件一样读取内存映射文件
    data = mmapped_file[:1024]
    mmapped_file.close()

使用 aiofiles 实现异步文件 I/O

对于 I/O 绑定的任务,执行异步文件操作可以显著提高代码的性能。aiofiles 库提供异步文件 I/O。

import asyncio
import aiofiles

async def read_file_async(file_path):
    async with aiofiles.open(file_path, 'r'as file:
        data = await file.read()
    return data
data = asyncio.run(read_file_async("large_file.txt"))

使用 aiofiles 可以并发执行多个文件的读取或写入,从而显著加快 I/O 绑定任务的速度。

网络和 API 调用

使用 requests 和  httpx 优化 HTTP 请求

在进行 HTTP 请求时,requests 和 httpx 等库可以通过连接池、请求重试和超时处理来提高性能。

import requests

response = requests.get("https://example.com/api/resource", timeout=5)

为了获得更好的性能,可以考虑使用支持异步请求和 HTTP/2 功能的 httpx

import httpx

async def fetch_data():
    async with httpx.AsyncClient() as client:
        response = await client.get("https://example.com/api/resource")
    return response
data = asyncio.run(fetch_data())

使用 FastAPI 构建高效的 REST API

FastAPI是一个现代网络框架,专为在 Python 中构建快速高效的 REST API 而设计。它使用uvicorn` ASGI 服务器,通过异步功能提供卓越的性能。

from fastapi import FastAPI

app = FastAPI()
@app.get("/hello")
async  def hello():
    return {"message""Hello, FastAPI!"}

利用 WebSockets 实现实时应用

WebSockets 提供全双工通信通道,允许客户端和服务器之间进行实时数据交换。Python 的 websockets 库可以帮助你轻松创建支持 WebSocket 的应用程序。

import asyncio
import websockets

async def websocket_server(websocket, path):
    message = await websocket.recv()
    await websocket.send(f"Hello, {message}!")
start_server = websockets.serve(websocket_server, "localhost"8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

数据库优化

与数据库的高效交互对高性能应用程序至关重要。Python 提供了多种优化数据库交互的工具和技术。

使用像 SQLAlchemy 这样的 ORM 来高效检索数据

像 SQLAlchemy 这样的对象关系映射(ORM)库可以简化数据库交互,并帮助你编写高效的数据检索代码。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
engine = create_engine("sqlite:///example.db")
Session = sessionmaker(bind=engine)
class Person(Base):
    __tablename__ = "person"
    id = Column(Integer, primary_key=True)
    name = Column(String)
session = Session()
people = session.query(Person).filter_by(name="John Doe")

编写优化的 SQL 查询

编写高效的 SQL 查询可以大大提高应用程序的性能。优化 SQL 查询的一些技巧包括

  • 在经常用于过滤或排序的列上使用索引
  • 使用 LIMIT 和 OFFSET 限制返回的行数
  • 使用 EXPLAIN 关键字分析查询执行计划

采用数据库结果缓存策略

缓存数据库结果可以避免冗余查询,从而大大加快应用程序的速度。使用 Python 内置的缓存机制或外部包(如 redis 或 memcached)来实现缓存。

import redis

cache = redis.Redis(host= 'localhost', port=6379)
def get_data_from_cache(key):
    data = cache.get(key)
    if data:
        return data.decode()
    else:
        return None
def store_data_in_cache(key, value):
    cache.set(key, value)

开发优化的 Python 库和部署

创建高效的库和部署对于确保 Python 应用程序在生产中良好运行至关重要。

使用 Cython 创建高效的 Python 包

Cython 允许你编写编译为 C 或 C++ 的 Python 代码,以提高性能。这对于计算密集型任务或与外部 C/C++ 代码集成时特别有用。

# my_module.pyx
def cython_function(double x):
    return x ** 2

# setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("my_module.pyx"))

利用 PyInstaller 等工具优化应用程序部署

PyInstaller 是为 Python 应用程序创建独立可执行文件、减少依赖性和简化部署的绝佳工具。

pip install pyinstaller
pyinstaller my_app.py

生产环境中的性能监控

监控生产环境中应用程序的性能对于识别瓶颈和确保最佳资源使用至关重要。新  Relic 和 Datadog 等工具可以帮助你监控应用程序的性能,并确定需要改进的地方。

写在最后

作为一名资深 Python 开发人员,不断学习和掌握最新的性能最佳实践是必不可少的。高效的代码不仅对增强用户体验和可扩展性至关重要,还能通过降低基础设施和云计算成本为公司节省资金。利用本指南中讨论的技术,你将能够编写出优化的 Python 代码。


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘 爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/183641
 
25 次点击