本文记录了 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 倍
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 倍
未完待续...