本文记录了 Python 编程中各种提速的小技巧,注意只记录小技巧。
列表解析 VS 生成器
优先选择 生成器
time.clock() [i for i in range(10000000)] # 1.04134576438 (i for i in range(10000000)) # 0.179256006437 print(time.clock())
差了 10 倍
list 查找 VS set 查找
优先选择 set 查找
data = (i for i in range(10000000)) # 0.179256006437 list_data = list(data) set_data = set(data) time.clock() 1098987 in list_data # 0.017s 左右 1098987 in set_data # 3.66553462739e-06 print(time.clock())
差了 10000 倍
在需要查找时,尽量生成 set,如果生成其他的,再转换成 set,这个转换比较耗时,具体可以测试下
双 list 查找 VS dict 查找
优先选择 dict 查找
list1 = range(10000000) list2 = range(10000000) dict_data = dict(zip(list1, list2)) time.clock() # list2[list1.index(888888)] # 0.015s dict_data[888888] # 5.86485540382e-06 print(time.clock())
差了 10000 倍
For VS While
优先选择 for 循环
time.clock() s, i = 0, 0 while i<10000000: # 1.55s i += 1 s += 1 # s = 0 # for i in range(10000001): # 1.35s # s += 1 print(time.clock())
while 通常需要判断 结束的条件,所以会慢
利用缓存机制加速递归函数
仅 python3 支持
普通递归
def fib(n): return (1 if n in (1, 2) else fib(n-1) + fib(n-2)) time.clock() fib(30) # 0.33s print(time.clock())
缓存优化的递归
from functools import lru_cache @lru_cache(100) def fib(n): return (1 if n in (1, 2) else fib(n-1) + fib(n-2)) time.clock() fib(30) # 2.6025295854463614e-05 print(time.clock())
差了 10000 倍
使用 numba 加速 python 函数
这个方法比较麻烦,后续我会专门写一篇博客介绍 numba, 这里只举个例子
注意,必须使用 numpy 标准库 作为 numba 加速对象
@jit def sum2d(arr): M, N = arr.shape result = 0.0 for i in range(M): for j in range(N): result += arr[i,j] return result time.clock() arr = np.array([range(100000)]) print sum2d(arr) print(time.clock()) # 带 @jit # 4999950000.0 # 0.482289656335 # 不带 @jit # 4999950000.0 # 0.039884608124
差了将近 10 倍
数据量大的计算使用jit才能发挥作用,简单的计算反而会慢
Python和Java一样是基于虚拟机的语言,并不是像C/C++那样将程序代码编译成机器语言再运行,而是解释一行执行一行,速度比较慢。使用Numba库的JIT技术编译以后,可以明显提高程序的运行速度。
numpy.func VS math.func
numpy 更适合 批处理数据
# encoding:utf-8 import time import math import numpy as np time.clock() # for i in range(1, 1000000): # # math.log(i) # 0.377321537556 # np.log(i) # 1.5135847542 # 逐个操作, numpy 效率更低 np.log(range(1, 1000000)) # 0.124642653573 # 批量处理 才是 numpy 的强项 print(time.clock())
差了 3 倍
动态扩容 VS 预分配内存
动态扩容就是事后增加行或者列;预分配内存就是事先定好行和列
# encoding:utf-8 import time import numpy as np import pandas as pd time.clock() # data = pd.DataFrame(columns=range(26)) # 动态扩容,15s 以上 data = pd.DataFrame(np.zeros((10000, 26))) # 预分配内存, 2s for i in range(10000): data.loc[i, :] = range(i, i+26) print(time.clock())
差了 7 倍
未完待续...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)