Expert Python Programming Notes
0x00 订阅
0x01 目录
语法最佳实践
命名最佳实践
包管理
代码部署
使用其他语言扩展Python
代码管理
文档构建
测试驱动开发
并发编程
设计模式
0x01 类级别以下的语法最佳实践
TODO
0x02 类级别以上的语法最佳实践
TODO
0x03 优化技术
可能会降低程序运行速度的情况:
基本内置类型使用不当
硬件资源使用模式与执行环境不匹配
过于长时间地等待来自第三方API或后台服务的响应
概率型数据结构
常用于键/值存储系统中加速键查找。
一些流行的概率型数据结构:
近似成员查询(AMQ, Approximate membership query)
布隆过滤器(Bloom Filter)
HyperLogLog
缓存技术
技术概念
确定性缓存:针对确定性函数,给定完全相同的输入,确定性函数总是返回相同的值。
非确定性缓存: 针对非确定性函数(每次执行可能给出不同的结果),需要判断缓存值的有效时间,在定义的时间段过去后所存储的结果被认为是陈旧的,需要刷新缓存值。
适合使用缓存的场景
查询数据库的可调用项的结果
渲染为静态值的可调用项的结果:如文件内容、Web请求、PDF渲染
执行复杂计算的确定性可调用对象的结果
全局映射,用于跟踪到期时间的值,如Web会话对象
需要经常和快速访问的结果
保存通过Web服务获得的第三方API的结果,减少网络延迟,提高性能并且节省费用。
如何缓存
简单的方法:进程空间中保存的全局数据结构,如dict
复杂:设置专门的缓存服务
内置函数
functools.lru_cache
functools — Higher-order functions and operations on callable objects — Python 3.12.3 documentation
代码示例
以递归计算斐波那契数列的函数为例,不实用缓存时,平均每次运算耗时0.12s
from time import perf_counter
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
if __name__ == '__main__':
count = 10
start = perf_counter()
for _ in range(count):
print(fib(30))
print(f"Time: {(perf_counter() - start)/count}")
若使用lru_cache(最近最少使用缓存,LRU),由于避免了多次耗时的重复计算,效率大幅提高
# @Author: weirdgiser
# @Time: 2024/5/19
# @Function:
from functools import lru_cache
from time import perf_counter
@lru_cache(maxsize=10)
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
if __name__ == '__main__':
count = 10
start = perf_counter()
for _ in range(count):
print(fib(30))
print(f"Time: {(perf_counter() - start)/count}")
缓存服务
- Memcached